Re: Re: Timing runs for the last part of my previous post

*To*: mathgroup at smc.vnet.net*Subject*: [mg62099] Re: [mg62056] Re: Timing runs for the last part of my previous post*From*: "Oyvind Tafjord" <tafjord at wolfram.com>*Date*: Fri, 11 Nov 2005 02:52:07 -0500 (EST)*References*: <dkshq9$jei$1@smc.vnet.net> <200511100750.CAA07305@smc.vnet.net>*Sender*: owner-wri-mathgroup at wolfram.com

----- Original Message ----- From: "Peter Pein" <petsie at dordos.net> To: mathgroup at smc.vnet.net Subject: [mg62099] [mg62056] Re: Timing runs for the last part of my previous post > Matt schrieb: >> OK, >> After I posted my earlier message (the one entitled "'Good' or >> 'Proper' Mathematica coding habits question"), I decided to try some >> timings for the last code sample I had a question on (the one trying to >> extract all sublists where each element of a sublist had to be >> negative). Here's what I found: >> >> This table was generated, then used for all the approaches: >> values = Table[{Random[Real, {-2, 2}] i, Random[Real, {-2, 2}] i}, {i, >> 1, 2000}]; >> >> Approach #1: > > I modified the testFunc slightly (see below) > >> And the test run was: >> >> Timing[Do[testFuncOne[], {10^3}]][[1]] >> Timing[Do[testFuncTwo[], {10^3}]][[1]] >> Timing[Do[testFuncThree[], {10^3}]][[1]] >> >> The results obtained were 13.625, 12.812, and 19.11 Seconds. So, it >> appears that of the methods I tried, that Approach 2 is marginally >> better than Approach 1, and both Approach 1 and Approach 2 are better >> than Approach 3. Is it correct to assume from this that Fold will >> almost always be better than Map, given that other potential variants >> are kept similar? Or, because the difference is so small, that for >> most applications, I should go with whatever approach is quicker to >> 'code up'? >> >> Thanks, >> >> Matt >> >> > > Hi Matt, > > one has to keep in mind that there's no compiler, which could alter loop > handling. It is possible to use a While-loop as efficient as the Fold > approach for this task. But nothing beats built-in kernel functions: > > values = Table[i*(4 Random[] - 2), {i, 2000}, {2}]; > > testFunc[1][] := > Module[{negElems = {}}, > (If[Negative[First[#1]] && Negative[Last[#1]], > negElems = {negElems, #1}] & ) /@ values; > Partition[Flatten[negElems], 2]] > > testFunc[2][] := > Module[{negElems = {}}, > Fold[ > If[Negative[First[#2]] && Negative[Last[#2]], > negElems = {negElems, #2}] & , > {1, 1}, values]; > Partition[Flatten[negElems], 2]] > > testFunc[3][] := > Module[{negElems = {}, ii = 1 + Length[values]}, > While[--ii > 0, > If[Negative[values[[ii, 1]]] && Negative[values[[ii, 2]]], > negElems = {values[[ii]], negElems}]]; > Partition[Flatten[negElems], 2]] > > testFunc[4][] := > Cases[values, {x_?Negative, y_?Negative}]; > > The test run is: > > In[6]:= > First /@ (res = Timing[Do[testFunc[#1][], {1000}]]& /@ Range[4]) > Out[6]= > {11.39 *Second, > 11.141*Second, > 11.172*Second, > 4.375*Second} > > In[7]:= > SameQ @@ Last /@ res > Out[7]= > True > > The difference between the first three methods is so small that a > garbage collection _could_ be responsible (I think). But with the kernel > function Cases you don't have to pick elements, build a very nested > list, flatten and partition it. And it is faster to 'code up' too. > > Have fun discovering Mathematica, > Peter Here's yet another way which is about 30% faster then testFunc4: Pick[values, Plus @@ Sign[#] & /@ values, -2] At some point you'll need to process all pairs in the list, so it's faster to do this up front, in an effective way, and then use Pick to get the elements you want. Oyvind Tafjord Wolfram Research

**References**:**Re: Timing runs for the last part of my previous post***From:*Peter Pein <petsie@dordos.net>