Timing differences

*To*: mathgroup at smc.vnet.net*Subject*: [mg63096] Timing differences*From*: "Trevor Baca" <trevorbaca at gmail.com>*Date*: Wed, 14 Dec 2005 04:35:58 -0500 (EST)*Sender*: owner-wri-mathgroup at wolfram.com

The question towards the end asks how there can be a timing difference of 4 or 5 orders of magnitude with the definition of only a single extra function. If we make a toy type called labelledInteger and overload Plus[ ] to define addition between labelledIntegers, we might get very satisfactory results, like this: In[1]:= labelledIntegerQ[li_]:=MatchQ[li,labelledInteger[_Integer,label_String]] In[2]:= labelledInteger/:Plus[l___labelledInteger]:= labelledInteger[Total[First/@{l}],"total"] In[3]:= t=Flatten[Table[labelledInteger[n,"foo"],{n,1,10}]] Out[3]= {labelledInteger[1,"foo"],labelledInteger[2,"foo"],labelledInteger[3,"foo"], labelledInteger[4,"foo"],labelledInteger[5,"foo"],labelledInteger[6,"foo"], labelledInteger[7,"foo"],labelledInteger[8,"foo"],labelledInteger[9,"foo"], labelledInteger[10,"foo"]} In[4]:= Timing[Total[t]] Out[4]= {0.000486 Second,labelledInteger[55,"total"]} Fractions of a second is good. But now, if we do the exact same thing (starting a new session with the kernel) but with the addition of overloading Plus[ ] a second time (to define addition between a labelledInteger and a normal integer) then we get MUCH slower results: In[1]:= labelledIntegerQ[li_]:=MatchQ[li,labelledInteger[_Integer,label_String]] In[2]:= labelledInteger/:Plus[l___labelledInteger]:= labelledInteger[Total[First/@{l}],"total"] In[3]:= labelledInteger/:l_labelledInteger+n_Integer:= labelledInteger[First[l]+n,Last[l]] In[4]:= labelledInteger[10,"foo"]+7 Out[4]= labelledInteger[17,"foo"] In[5]:= t=Flatten[Table[labelledInteger[n,"foo"],{n,1,15}]] Out[5]= {labelledInteger[1,"foo"],labelledInteger[2,"foo"],labelledInteger[3,"foo"], labelledInteger[4,"foo"],labelledInteger[5,"foo"],labelledInteger[6,"foo"], labelledInteger[7,"foo"],labelledInteger[8,"foo"],labelledInteger[9,"foo"], labelledInteger[10,"foo"],labelledInteger[11,"foo"], labelledInteger[12,"foo"],labelledInteger[13,"foo"], labelledInteger[14,"foo"],labelledInteger[15,"foo"]} In[6]:= Timing[Total[t]] Out[6]= {16.7988 Second,labelledInteger[120,"total"]} 17 seconds is bad. What on earth is going on here? One workaround is clear: create a named function for either or both types of addition and don't overload Plus[ ] twice this way; but what I really want to know is why the second definition causes such a dramatic increase in timing. Trevor.