RE: puzzling difference in speed

*To*: mathgroup at smc.vnet.net*Subject*: [mg34737] RE: [mg34688] puzzling difference in speed*From*: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.com>*Date*: Tue, 4 Jun 2002 03:41:48 -0400 (EDT)*Sender*: owner-wri-mathgroup at wolfram.com

> -----Original Message----- > From: Johannes Ludsteck To: mathgroup at smc.vnet.net > [mailto:johannes.ludsteck at wiwi.uni-regensburg.de] > 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 > Johannes, just to to give comparable timings on my machine: 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.26 Second, Null} In[4]:= Timing[t3 = Array[Plus, Dimensions[t1]];] Out[4]= {2.574 Second, Null} In[5]:= dim = Dimensions[t1] Out[5]= {50, 50, 50} In[6]:= 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 evaluated) 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: In[7]:= 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 In[9]:= 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: In[10]:= 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 site! 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". -- Hartmut

**Follow-Ups**:**Re: RE: puzzling difference in speed***From:*"Fred Simons" <f.h.simons@tue.nl>