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.