MathGroup Archive 2009

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

Search the Archive

Re: Speeding up code

  • To: mathgroup at smc.vnet.net
  • Subject: [mg100437] Re: Speeding up code
  • From: David Bailey <dave at removedbailey.co.uk>
  • Date: Wed, 3 Jun 2009 05:29:23 -0400 (EDT)
  • References: <h02vo6$8ek$1@smc.vnet.net> <h050kr$abg$1@smc.vnet.net>

pfalloon wrote:
> On Jun 2, 8:43 pm, bori... at sas.upenn.edu wrote:
>> Hello all,
>>
>> I need some advise on speeding up code. Here is a section that is executed more
>> than 100000 times during my simulations. Currently it takes about 0.06s per
>> execution which is about 80% of the total time for the simulation. The
>> subsection MITime itself takes 0.03s out of those 0.06s. All variables not
>> defined in this section are predefined. Anyone have suggestions?
>>
>> MDTime = First[
>>   Timing[
>>    yps = Table[(ys[[i]] + ys[[i - 1]])/2, {i, 2, ngrid}];
>>    yms = Table[(ys[[i]] - ys[[i - 1]]), {i, 2, ngrid}];
>>    ups = Table[(us[[i]] + us[[i - 1]])/2, {i, 2, ngrid}];
>>    ums = Table[(us[[i]] - us[[i - 1]]), {i, 2, ngrid}];
>>    Etus = Table[rrms[[i]]*Exp[-ups[[i]]], {i, 1, ngrid - 1}];
>>    (*Etu2s=Table[Exp[-ups[[i]]/2],{i,1,ngrid-1}];*)
>>
>>    SqEts = Table[
>>      rrpms[[i]]*sqrrs[[i]]*Exp[-ups[[i]]/2]*acubed*rba, {i, 1,
>>       ngrid - 1}];
>>    ElemEIEI = Table[N[SqEts[[i]]/4, Precis], {i, ngrid - 1}];
>>    ElemOIOI = Table[N[-Etus[[i]]/2, Precis], {i, ngrid - 1}];
>>    ElemOIOI1 =
>>     Table[N[yps[[i]]*Etus[[i]]/2, Precis], {i, ngrid - 1}];
>>    Es[[ngrid*nvar]] = N[Exp[us[[ngrid]]] - rrs[[ngrid]], Precis];
>>    Es[[1]] = Exp[us[[1]]] - rrs[[1]]*ys[[1]];
>>    For[i = 1, i <= ngrid - 1, i++,
>>     Es[[nvar*i]] = N[yms[[i]] + Yds[[i]] - SqEts[[i]], Precis];
>>     Es[[nvar*i + 1]] = N[ums[[i]] - yps[[i]]*Etus[[i]], Precis];
>>     ];
>>    (* Table of rules used to create the Sms matrix*)
>>
>>    MITime = First[
>>      Timing[
>>       DataSAP = Join[
>>         Table[{nvar*i, nvar*(i - 1) + 1} -> N[-1., Precis], {i,
>>           ngrid - 1}],
>>         Table[{nvar*i, nvar*(i - 1) + 2} -> ElemEIEI[[i]], {i,
>>           ngrid - 1}],
>>         Table[{nvar*i, nvar*(i - 1) + 3} -> N[1., Precis], {i,
>>           ngrid - 1}],
>>         Table[{nvar*i, nvar*(i - 1) + 4} -> ElemEIEI[[i]], {i,
>>           ngrid - 1}],
>>         Table[{nvar*i + 1, nvar*(i - 1) + 1} -> ElemOIOI[[i]], {i,
>>           ngrid - 1}],
>>         Table[{nvar*i + 1, nvar*(i - 1) + 2} ->
>>           ElemOIOI1[[i]] - 1., {i, ngrid - 1}],
>>         Table[{nvar*i + 1, nvar*(i - 1) + 3} -> ElemOIOI[[i]], {i,
>>           ngrid - 1}],
>>         Table[{nvar*i + 1, nvar*(i - 1) + 4} ->
>>           ElemOIOI1[[i]] + 1., {i, ngrid - 1}]]
>>       ]
>>      ];
>>    DataSA = Prepend[DataSAP, {1, 2} -> N[Exp[us[[1]]], Precis]];
>>    DataSA =
>>     Prepend[DataSA, {nvg, nvg} -> N[Exp[us[[ngrid]]], Precis]];
>>    DataSA = Prepend[DataSA, {1, 1} -> N[-rrs[[1]], Precis]];
>>    Sms = SparseArray[DataSA];
>>   ]
>> ];
>>
>> Best regards
>> Alexander
> 
>>From a quick look at the code, I would suggest trying the following:
> 
> 1. Avoid "growing" the DataSA list using Prepend: this is in general a
> bad way to do it. It looks like you could just bring those last couple
> of operations inside the Join.
> 
> 2. Try using Compile: this is useful for cases where you are doing
> many simple operations.
> 
> 3. (Possibly the most important but requires a bit more thought): it
> helps a lot if you vectorize your code. That is, instead of something
> like (the following is a trivial example):
> 
>     x = Table[y[[i]] + z[[i]], {i, n}]
> 
> use
> 
>     x = y + z
> 
> Depending on how many elements of the arrays you are accessing, you
> may need to use functions like Take, Drop, Most, Rest, Cases, Select,
> etc.
> 
> If you can formulate your calculation in vector form it is likely to
> be close to optimal since Mathematica's built-in list operations are
> highly optimized.
> 
Adding to those suggestions, we never got to see the original data that 
this code operates on. If at all possible, arrays should be of just one 
type - e.g. Real - and if this is appropriate, it might help to apply N 
to these arrays to make sure this is so. This will be particularly 
relevant if you are able to follow Pfalloon's suggestion to vectorise 
your code.

Unfortunately, optimising code is a fairly tricky process, because it is 
all too easy to optimise the wrong part of the code - so even though you 
sped it up, it only ever accounted for 1% of the total run time, and you 
don't see any improvement...

David Bailey
http://www.dbaileyconsultancy.co.uk


  • Prev by Date: Re: proper way of posing a non-autonomous ode in mathematica?
  • Next by Date: Re: Speeding up code
  • Previous by thread: Re: Speeding up code
  • Next by thread: Re: Speeding up code