Sign up ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I noticed an over 10x performance drop on Mathematica v9.0.1 (as Oleksandr R. commented, also v8) compared with v7.01 for this code:

SetSystemOptions["CatchMachineUnderflow" -> False];
 Fold[{(#[[1]] Sin[10.5])/(#2 + 1), #[[2]] + Tan[#[[1]]]} &,
   {Sin[10.5], 1.0}, N@Range[10^6]] 

I got {0.184287, {0., 0.105747}} on v7, but got {2.311755, {0., 0.105747}} on v9. Note that the Do[...] version of above code needs about 2 seconds. Thus I suspect that on v9 the Fold code is not properly auto-compiled.

Is this a regression? (Also is there a way to see if auto-compile worked or not?)

Additional information

I compared that in v7 and v9 the CompileOptions are the same (except that v9 has some options that are not present in v7):


{"CompileOptions" -> {"ApplyCompileLength" -> [Infinity], "ArrayCompileLength" -> 250, "AutoCompileAllowCoercion" -> False, "AutoCompileProtectValues" -> False, "AutomaticCompile" -> False, "BinaryTensorArithmetic" -> False, "CompileAllowCoercion" -> True, "CompileConfirmInitializedVariables" -> True, "CompiledFunctionArgumentCoercionTolerance" -> 2.10721, "CompiledFunctionMaxFailures" -> 3, "CompileDynamicScoping" -> False, "CompileEvaluateConstants" -> True, "CompileOptimizeRegisters" -> False, "CompileParallelizationThreshold" -> 10, "CompileReportCoercion" -> False, "CompileReportExternal" -> False, "CompileReportFailure" -> False, "CompileValuesLast" -> True, "FoldCompileLength" -> 100, "InternalCompileMessages" -> False, "ListableFunctionCompileLength" -> 250, "MapCompileLength" -> 100, "NestCompileLength" -> 100, "NumericalAllowExternal" -> False, "ProductCompileLength" -> 250, "ReuseTensorRegisters" -> True, "SumCompileLength" -> 250, "SystemCompileOptimizations" -> All, "TableCompileLength" -> 250}}

To compare, I also tried the following code, where the performance on v7 and v9 are roughly the same (v9 is on average 5% more slowly though).

AbsoluteTiming@Fold[# + Sin[#2] &, 1.0, Range[10^6]]

A difference is that here the first argument of function in Fold is a number, and in the problematic example, the first argument is a list.

PS: I noticed this issuee during a discussion at About auto-compiling and performance between Do and Fold . But considering this regression issue is a different question, I ask here separately.

share|improve this question
Note that it is not customary to use the "bugs" tag until we have confirmation from WRI or consensus in the community that it is really a bug. However, in this particular case, the regression is so obvious that tagging it as a bug right away seems justified. – Oleksandr R. Feb 17 '14 at 8:26
Incidentally, version 8 is somehow intermediate between 7 and 9. Its performance is closer to that of version 9 than to 7, but about 10% faster than the former. So I think it would be fair to say that the major regression occurred in version 8, but nobody noticed until now. – Oleksandr R. Feb 17 '14 at 8:29
I get {5.068002, {0., 0.105747}} on version 10. Seems like it wasn't fixed. – Jacob Akkerboom Jul 9 '14 at 21:26
This bug is still present in 10.2 – RunnyKine Aug 4 at 9:56
After seeing @ilian's answer, I have to reconsider the status of this as a bug, because it is obviously caused by numerical overflow in user code. I am de-tagging appropriately. If anyone disagrees, please roll back and let's discuss it. – Oleksandr R. Sep 6 at 20:36

2 Answers 2

up vote 13 down vote accepted

The reason for this behavior is that autocompilation always uses settings equivalent to "RuntimeOptions" -> {"Quality", "WarningMessages" -> False}.

As previously noted in Silvia's answer, the automatic compilation is invoked for input exceeding

SystemOptions["CompileOptions" -> "FoldCompileLength"]

(* {"CompileOptions" -> {"FoldCompileLength" -> 100}} *)

however, when $n$ becomes greater than 165, the compiled function interpreter switches to uncompiled evaluation because of machine underflow. This can be seen if we compile the function ourselves,

cf0 = Compile[{{arg, _Real, 1}}, Fold[{(#[[1]] Sin[10.5])/(#2 + 1), 
        #[[2]] + Tan[#[[1]]]} &, {Sin[10.5], 1.0}, arg], "RuntimeOptions" -> "Quality"];


(* {6.37932*10^-308, 0.105747} *)


(* CompiledFunction::cfn: Numerical error encountered at instruction 12; 
proceeding with uncompiled evaluation. >>

  {-3.360393999426673*10^-310, 0.105747} 


where the first element in the last result is not a machine number.

The speed can be recovered by turning off underflow checking, for example

cf = Compile[{{arg, _Real, 1}}, Fold[{(#[[1]] Sin[10.5])/(#2 + 1), 
       #[[2]] + Tan[#[[1]]]} &, {Sin[10.5], 1.0}, arg], "RuntimeOptions" -> "Speed"];


(* {0.202218, {0., 0.105747}} *)

As for why version 7 is different, I am not completely sure. The more fine-grained control allowed by "RuntimeOptions" did not exist before the compiler overhaul in version 8. Earlier than that, it is possible that all machine arithmetic exception handling was controlled by the legacy "CatchMachineUnderflow" system option (first implemented in 1999).

Given that automatic compilation is invisible to the user, I am inclined to believe that always using the safer "RuntimeOptions" -> "Quality" was a conscious design choice. Explicit compilation should be used if other exception handling scenarios are desired.

share|improve this answer
Based on your answer I'm strongly inclined to remove the "bugs" tag. Thanks for looking into this issue. – Oleksandr R. Sep 6 at 20:26
Thanks for your informative answer! I didn't realize there is an underflow. – Silvia Sep 7 at 2:20

(This is not an answer, but only a phenomenon I observed. And I think it might be a bug.)

I think in version 9, Mathematica fails to compile the Fold for $n\geq 166$ where $n$ is the integer number in Range. The precise threshold may be different from OS to OS, but I suspect this phenomenon exists in all version 9.

Note the default "FoldCompileLength" is 100:

"CompileOptions" /. SystemOptions["CompileOptions"] // "FoldCompileLength" /. # &


Now take a look at the steps of the whole evaluation chain for different $n$:

evalSteps = Map[(
                    steps = 0;
                    TraceScan[steps++ &,
                        Fold[{(#1[[1]] Sin[10.5])/(#2 + 1), #1[[2]] + 
                                        Tan[#1[[1]]]} &, {Sin[10.5], 1.0}, N[Range[#]]],
                        TraceInternal -> True, TraceOff -> _Message];
                    {#, steps}) &,
            Range[1, 500]];

ListLinePlot[evalSteps, PlotStyle -> Red, Frame -> True, PlotRange -> All]

strange failure of compile?

So it seems to suggest that auto-compilation occurs correctly at $n=100$, but strangely fails for $n\geq 166$.

However, a close checking of the evaluation chains returned from Trace (along with the levelIndentFunc I described in this question) reveals that auto-compilation might occur correctly for $n\geq 166$ too, but mma somehow falls back to uncompiled version after then. The following comparison is between $n=166$ and $n=165$:

comparison between succeeded and failed cases

share|improve this answer
I can confirm the exact same behaviour on Linux Mint Debian with both Mathematica 8 and 9. – sebhofer Apr 23 '14 at 8:37
@sebhofer Thanks for checking it! – Silvia Apr 23 '14 at 8:40
I confirm this behavior with Mathematica 8.0.4 under Windows. – Alexey Popkov Apr 23 '14 at 10:12

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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