static array litteral syntax using a library solution (no GC and 40x faster!)
John Colvin
john.loughran.colvin at gmail.com
Sun Feb 3 05:18:03 PST 2013
On Sunday, 3 February 2013 at 09:23:01 UTC, timotheecour wrote:
> Static arrays suffer from:
>
> 1) bad implementation that allocates on the heap when we do:
> "int[3]=[1,2,3];"
>
> 2) lack of syntactic sugar to declare them on on the fly, eg
> when we want to pass a static array to a function without
> declaring an intermediate variable. See my proposal for "auto
> x=[1,2,3]s" here:
> http://permalink.gmane.org/gmane.comp.lang.d.general/90035,
> which would allow one to pass a static array to a function eg:
> fun([1,2,3]s) without having to do int[3] temp; fun(temp), when
> it's not passed by ref.
>
> If 90035 won't get implemented, what about a library solution?
>
> Below, we can construct a static array on the fly as:
> "auto x=S(1,2,3);"
> as opposed to:
> "int[3] x=[1,2,3]"
>
> advantages:
> a) can directly pass to a function without creating temp
> variable
> b) less verbose
> c) no heap allocations
> d) 40 times faster in the example below (even 2.3x faster than
> C, for some reason which eludes me)
>
>
> ----
> import std.stdio,std.conv;
> import std.traits:CommonType;
>
> auto S(T...)(T a) if(!is(CommonType!T == void )){ //check to
> prevent illegal stuff like S([],2)
> alias CommonType!T T0;
> T0[T.length]ret;
> foreach(i,ai;a)
> ret[i]=ai;
> return ret;
> }
>
> void main(){
> size_t n=1000000,z=0,i=0,j=0;
> for(i=0;i<n;i++){
> // auto
> a=S(cast(size_t)i,i+1,i+2,i+3,i+4,i+5,i+6,i+7,i+8,i+9); //time:
> 0.351 with LDC
>
> size_t[10] a=[i,i+1,i+2,i+3,i+4,i+5,i+6,i+7,i+8,i+9]; //time:
> 14.049 with LDC, 16s with dmd (-inline -O -release)
> for(j=0;j<9;j++){z+=a[j];}
> }
> TOC;
> writeln(z); //to prevent optimizing away result (?)
> }
> ----
>
>
>
> interestingly, this seems faster than the C version below. Why
> is that so?
>
> ----
> //test.c:
> #include <stdio.h>
> int main(){
> size_t n=100000000,z=0,i=0,j=0;
> for(i=0;i<n;i++){
> size_t a[10]={i,i+1,i+2,i+3,i+4,i+5,i+6,i+7,i+8,i+9};
> for(j=0;j<9;j++){z+=a[j];}
> }
> printf("%lu\n",z);
> return 0;
> }
> ----
> gcc -O2 test.c -o test && time ./test
> real 0m0.803s
Very interesting! Anything that beats c performance is a very big
plus for D.
Btw, you can replace the loop in S with
ret[] = a[];
Which should be even faster.
Also, to check that the assignment is being optimised away, try
using different data in each pass.
More information about the Digitalmars-d
mailing list