Re: Speeding up code
- To: mathgroup at smc.vnet.net
- Subject: [mg100423] Re: Speeding up code
- From: pfalloon <pfalloon at gmail.com>
- Date: Wed, 3 Jun 2009 01:11:00 -0400 (EDT)
- References: <h02vo6$8ek$1@smc.vnet.net>
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.