Re: Timing differences

• To: mathgroup at smc.vnet.net
• Subject: [mg63126] Re: Timing differences
• From: Peter Pein <petsie at dordos.net>
• Date: Thu, 15 Dec 2005 03:06:34 -0500 (EST)
• References: <dnopi7\$2hn\$1@smc.vnet.net>
• Sender: owner-wri-mathgroup at wolfram.com

```Trevor Baca schrieb:
> 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.
>

Hi Trevor,

use
labelledInteger /: Plus[l__labelledInteger /; Length[{l}] > 1] :=
labelledInteger[Plus @@ First /@ {l}, "total"];

With this definition I get
Short[(1/Second)*First /@ (tm = Timing[Total[Table[labelledInteger[n, "foo"],
{n, #1}]]]& /@ Range[100])]
--> {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,<<78>>,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.}

Last[tm]
--> {0.*Second, labelledInteger[5050, "total"]}

I can't explain, why it takes so much time, when defining Plus for
labeledInteger-sequences of arbitrary length. But of course length 0 is
supeflous and since Plus has attribute OneIdentity (Plus[x]==x --> True), it
is sufficient to define the special behaviour for sequences of length two or more.

Peter

```

• Prev by Date: Arriving at a design space using mathematica
• Next by Date: Re: Opener Icons for cell group.
• Previous by thread: Timing differences
• Next by thread: Unexpected non-evaluation problem