MathGroup Archive 2002

[Date Index] [Thread Index] [Author Index]

Search the Archive

RE: puzzling difference in speed

> -----Original Message-----
> From: Johannes Ludsteck
To: mathgroup at
> [mailto:johannes.ludsteck at]
> Sent: Saturday, June 01, 2002 10:29 AM
> Subject: [mg34737] [mg34688] puzzling difference in speed
> Dear MathGroup members,
> is there anyone out who can explain why
> computation of t2 (see below) is about 10 times faster than
> computation of t3? (Note that t2 == t3).
> The difference cannot be explained by the computation
> time of Dimensions[t1], as Out[5] and Out[6] show.
> Of course, the answer is not important for my work,
> but the puzzling difference in computation time reduces
> my confidence that Mathematica manages efficiency
> problems of computation in a smart and *transparent* manner.
> In[1]:= 		n=50;
> In[2]:=		t1=Table[0.0,{n},{n},{n}];
> In[3]:=		Timing[t2=Array[Plus,{n,n,n}];]
> Out[3]=		{0.05 Second,Null}
> In[4]:=		Timing[t3=Array[Plus,Dimensions[t1]];]
> Out[4]=		{0.55 Second,Null}
> In[5]:=		Timing[dim=Dimensions[t1]]
> Out[5]=		{0. Second,{50,50,50}}
> In[8]:=		Timing[t4=Array[Plus,dim];]
> Out[8]=		{0.49 Second,Null}
> By the way: if one tries to  compile the stuff, things
> become even more strange:
> In[7]:= comp1=Compile[{{t,_Real,3}},
> 		Array[Plus,Dimensions[t]]]
> Compile::cpiter: Iterator at position 2 of Array[Plus,Dimensions[t]] 
> cannot be compiled; evaluation will use the uncompiled function.
> Why does Mathematica refute to compile the code?
> Dimensions[t] must be a list of three integers,
> since t is a rank 3 tensor. So try to help Mathematica:
> In[8]:= comp2=Compile[{{t,_Real,3}},
>     		With[{dim=Dimensions[t]},Array[Plus,dim]]]
> Compile::cpiter: Iterator at position 2 of Array[Plus,dim] cannot be \
> compiled; evaluation will use the uncompiled function.
> Again Mathematica does not understand. So try to be more
> patient and considerate with the compiler:
> In[9]:= comp3=Compile[{{t,_Real,3}},
>     Block[{n1,n2,n3},
>       {n1,n2,n3}=Dimensions[t];
>       Array[Plus,{n1,n2,n3}]]]
> Out[9] CompiledFunction[...]
> At last now Mathematica does the job.
> If you type Timing[compi[t1];]
> for i in {1,2,3}, you will see that Mathematica is really
> confused with comp1 and comp2, since it even reports external
> evaluation errors.
> Is there any straightforward explanation of such behaviour?
> Best regards,
> 	Johannes Ludsteck
> <><><><><><><><><><><><>
> Johannes Ludsteck
> Economics Department
> University of Regensburg
> Universitaetsstrasse 31
> 93053 Regensburg
> Phone +49/0941/943-2741


just to to give comparable timings on my machine:

In[1]:= n = 50;
In[2]:= t1 = Table[0.0, {n}, {n}, {n}];

Timing[t2 = Array[Plus, {n, n, n}];]
Out[3]= {0.26 Second, Null}

Timing[t3 = Array[Plus, Dimensions[t1]];]
Out[4]= {2.574 Second, Null}

In[5]:= dim = Dimensions[t1]
Out[5]= {50, 50, 50}

Timing[t4 = Array[Plus, dim];]
Out[6]= {2.403 Second, Null}

Obviously the computing machinery for Array behaves differently when the
dimensions are given explicitly or introduced as an expression (to be

In[8]:= Attributes[Array]
Out[8]= {Protected}

...doesnt give a clue to it (no Hold attributes!), but Array is subject to a
special evaluation sequence, such anything is possible (and subject to
change; we simply don't know, not being kernel insiders).

This even doesn't work with With:

With[{d = Dimensions[t1]}, Timing[t5 = Array[Plus, d];]]
Out[7]= {2.394 Second, Null}

But if you want to have fast evaluation *and* programmed (dynamic)
dimensions you may use

Module[{d1, d2, d3}, {d1, d2, d3} = Dimensions[t1]; 
  Timing[t6 = Array[Plus, {d1, d2, d3}];]]
Out[9]= {0.23 Second, Null}

If you even don't know the rank of t1 you may use:

Evaluate[alld = Table[Unique[d], {TensorRank[t1]}]] = Dimensions[t1]; 
   Timing[t7 = Array[Plus, alld];]
Out[10]= {0.26 Second, Null}

In[11]:= t2 == t3 == t4 == t5 == t6 == t7
Out[11]= True

To understand(?) -- what is understanding? -- this load

In[12]:= << Developer`

In[13]:= PackedArrayQ /@ {t2, t3, t4, t5, t6, t7}
Out[13]= {True, False, False, False, True, True}

In[14]:= ByteCount /@ {t2, t3, t4, t5, t6, t7}
Out[14]= {500064, 2571424, 2571424, 2571424, 500064, 500064}

When which kernel function delivers packed arrays is something that must be
explored in each case -- at least I cannot give you a general rule. Perhaps
you (and me too) should read everything about packed arrays at Wolfram's web

Your observations with compile are just additional evidence for that special
behaviour of Array: 

In[18]:= Timing[tc3 = comp3[t1];]
Out[18]= {0.26 Second, Null}

In[19]:= PackedArrayQ[tc3]
Out[19]= True

So comp3 just uses a similar evaluation as my In[9] above. Anyway,
compilation cannot give you advantages in this case (to the contrary!), we
have just to persuade Array to evaluate "the right way".


  • Prev by Date: RE: RE: RE: Define a function
  • Next by Date: RE: Re: Re: Function as an argument of the function
  • Previous by thread: RE: puzzling difference in speed
  • Next by thread: Re: RE: puzzling difference in speed