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).
Answer
The reason is that Mathematica tries to compile the code for sufficiently long Table
s, Sum
s, and Product
s. 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.
Comments
Post a Comment