Re: Timing runs for the last part of my previous post
- To: mathgroup at smc.vnet.net
- Subject: [mg62056] Re: Timing runs for the last part of my previous post
- From: Peter Pein <petsie at dordos.net>
- Date: Thu, 10 Nov 2005 02:50:41 -0500 (EST)
- References: <dkshq9$jei$1@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
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
- Follow-Ups:
- Re: Re: Timing runs for the last part of my previous post
- From: "Oyvind Tafjord" <tafjord@wolfram.com>
- Re: Re: Timing runs for the last part of my previous post