MathGroup Archive 2005

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

Search the Archive

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