5
$\begingroup$

im using Map on a List like this:

cube= {{1, 1, 1}, {1, 1, 2}, {1, 1, 3}, {1, 1, 4}, ... , {5, 5, 4}, {5, 5, 5}}

Mapping the whole List with 125 entries takes like 2.5s.

AbsoluteTiming[
 Map[Apply[d[[#1, #2, #3]] &, #] &, cube];
 ]

{2.552146, Null}

Mapping in two sublists with less than 100 entries the whole thing takes nearly no time.

 AbsoluteTiming[
     Join[
       Map[Apply[d[[#1, #2, #3]] &, #] &, cube[[1 ;; 99]]],
       Map[Apply[d[[#1, #2, #3]] &, #] &, cube[[100 ;; 125]]]
       ];

 ]

{0., Null}

Why is there a huge performance gap? An how do I avoid it except splitting my list?

$\endgroup$
4
  • $\begingroup$ Btw your cube is equal to Tuples[Range[5],3], just so you know :). $\endgroup$ Commented Jul 16, 2014 at 10:56
  • 1
    $\begingroup$ @TeakeNutma I bet ... here really means {2,9,12},{tweedledee,tweedledum, "tweedleDUN"}. This reminds me of a book by a mathematician I once read which pointed out a remarkable device that physicists have come up with, namely, $\ldots$, which allows them to solve practically any problem simply by omission. $\endgroup$
    – acl
    Commented Jul 16, 2014 at 11:04
  • 1
    $\begingroup$ Can you show what d is? and isn't this the same : Map[d[[Sequence @@ #]] &, cube]? I cant reproduce this slowness even on much larger lists. $\endgroup$
    – george2079
    Commented Jul 16, 2014 at 15:13
  • $\begingroup$ @george2079 I've added an example in my answer, take a look $\endgroup$
    – acl
    Commented Jul 16, 2014 at 20:55

1 Answer 1

9
$\begingroup$

If you look at SystemOptions[], like so,

Column[
 OpenerView /@
  (Replace[SystemOptions[], Rule[x_, y_] -> List[x, y],
     1])
 ]

you see that under CompileOptions, if you click on the triangle to open it,

enter image description here

there is an option "MapCompileLength" -> 100. Set it to eg 10 and see it it helps (do SetSystemOptions["CompileOptions" -> {"MapCompileLength" -> 10}]).

This option determines the length of the list above which Mathematica (tries to) compile the function to be mapped.

EDIT: Example:

Here's some data:

Length[cube = Tuples[Range[10], 4]]

And here's a function which is a) inefficient on purpose, b) designed to be compilable as-is (that's why I localise s, so that Compile will work).

d = (Module[{s = 0}, Do[s = s + #[[i]]^2, {i, Length@#}];s] &)

Now, set the auto-compilation length for Map to 100 (the default):

SetSystemOptions["CompileOptions" -> {"MapCompileLength" -> 100}]

and now test:

Needs["GeneralUtilities`"]
Quiet@BenchmarkPlot[d /@ # &, cube[[1 ;; #]] &, Range[90, 110]]

enter image description here

$\endgroup$
4
  • $\begingroup$ Maybe I'm dense today. Your example got faster at length 100, which I understand, but the OP's got slower at length 100, which I do not understand. Am I missing something? $\endgroup$
    – Michael E2
    Commented Jul 16, 2014 at 23:32
  • $\begingroup$ @MichaelE2 oops, no, I am dense! You're right. Well then the example is inapplicable. Maybe they should just set the length to infinity and see what happens. $\endgroup$
    – acl
    Commented Jul 16, 2014 at 23:34
  • 1
    $\begingroup$ @acl maybe the compilation itself is fairly expensive, and not worth the 'payoff'? $\endgroup$ Commented Jul 17, 2014 at 13:49
  • 1
    $\begingroup$ @TaliesinBeynon that's the only explanation I could think of, too. Let's see when/if we are shown the function. It might involve lots of subexpressions so that time is spent on optimizing them, for example. $\endgroup$
    – acl
    Commented Jul 17, 2014 at 14:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.