MathGroup Archive 2005

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

Search the Archive

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


  • Prev by Date: Re: Re: Following Help Links with the Keyboard
  • Next by Date: Re: Re: 5.2 on suse 10.0 error
  • Previous by thread: Re: Timing runs for the last part of my previous post
  • Next by thread: Re: Re: Timing runs for the last part of my previous post