5
$\begingroup$

I have a weird performance problem in a nested sum, which I've reduced to the following test case:

testTab = Table[1.`20, {i, 188}, {j, 301}, {k, 20}];
test[] := Sum[testTab[[1, 1, 1]] Sum[testTab[[1, 1, 1]], {n, 1, 250}], {m, 1, 10}]
Monitor[test[], {n, m}]

Here the output from Monitor is {n, 1} for a second, then it changes to {n, 2}, and so on until I get the result of 2500.0000000000000000. Obviously, table accesses shouldn't be that slow.

Even more interestingly, if I change the summation limit of the inner sum from 250 to 249 or smaller, I don't get this slowdown, the result appears almost instantly. I can even make table dimensions way larger, but this 250→249 transition still results in drastic performance difference.

What's happening here? Is it a bug?

I'm using Mathematica "11.1.0 for Linux x86 (32-bit) (March 13, 2017)", but this problem also happens on "9.0 for Linux x86 (32-bit) (November 20, 2012)" and on "11.0.1 for Linux ARM (32-bit) (January 17, 2017)" (Raspberry Pi 3).

$\endgroup$
  • $\begingroup$ Same behavior in M8 $\endgroup$ – Bill Watts Dec 1 '17 at 7:46
8
$\begingroup$

The reason is that Mathematica tries to compile the code for sufficiently long Tables, Sums, and Products. The outer sum has 10 summands. That's too few. But starting the inner sum with 250 or more summands implies a compilation. 250 is the default value of the suboption "SumCompileLength" of the system option "CompileOptions":

"SumCompileLength" /. ("CompileOptions" /. SystemOptions[])

250

This compilation is done for each iteration of the outer Sum and induces some overhead. This is why it is a good idea to merge multiple sums into a single instance of Sum like this:

test2[] := 
 Sum[testTab[[1, 1, 1]] testTab[[1, 1, 1]], {n, 1, 250}, {m, 1, 10}]

Moreover, trying to use matrix-vector producs or Total may be even more efficient. Needless to say that nothing will beat testTab[[1, 1, 1]] 250 10 in this case.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Well of course nothing will beat it, I've already mentioned that it's a reduced test case. Anyway, is there any means of making SumCompileLength way higher to avoid hitting this? $\endgroup$ – Ruslan Dec 1 '17 at 8:00
  • 1
    $\begingroup$ Yes, for example SetSystemOptions[ "CompileOptions" -> {"SumCompileLength" -> \[Infinity]}]. Use at your own risk. $\endgroup$ – Henrik Schumacher Dec 1 '17 at 8:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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