MathGroup Archive 2005

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

Search the Archive

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.


  • Prev by Date: Re: Remote Mathematica kernels and SSH password
  • Next by Date: Re: Mathematica Programmer vs. Programming in Mathematica
  • Previous by thread: Re: Parametric Numerical Integral
  • Next by thread: Re: Timing differences