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