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