Are you definitely sure you need the error checking for NaN inside Compile?
The error checking seems to generate very inefficient compiled code. It basically only calls MainEvaluate, so you gain nothing by compiling.
data = Range[1000];
func /@ data; // AbsoluteTiming
func1 /@ data; // AbsoluteTiming
(* ==> {0.1280073, Null} *)
(* ==> {0.0140008, Null} *)
func =
Compile[{{length}}, (result = Sum[i^2, {i, length}];
If[NumberQ[result], result, Abort[]]), {{NumberQ[_],
True | False}}];
func1 = Compile[{{length, _Integer}}, Sum[i^2, {i, length}]];
data = Range[1000];
d1 = func /@ data; // AbsoluteTiming
d2 = func1 /@ data; // AbsoluteTiming
d1 == d2
(* ==> {0.1160067, Null} *)
(* ==> {0.0140008, Null} *)
(* ==> True *)
Needs["CompiledFunctionTools`"]
CompilePrint[func]
CompilePrint[func1]
(*
==> "
1 argument
1 Boolean register
4 Integer registers
7 Real registers
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes -> {}
R0 = A1
I1 = 0
R3 = 0.
Result = R2
1 V17 = MainEvaluate[ 2
Function[{length}, result = Sum[i , {i, length}]][ R0]]
2 B0 = MainEvaluate[ Function[{length}, NumberQ[result]][ R0]]
3 if[ !B0] goto 7
4 R5 = MainEvaluate[ Function[{length}, result][ R0]]
5 R2 = R5
6 goto 9
7 R1 = MainEvaluate[ Function[{length}, Abort[]][ R0]]
8 R2 = R1
9 Return
"
*)
(*
==> "
1 argument
9 Integer registers
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes -> {}
I0 = A1
I3 = 0
Result = I4
1 I4 = I3
2 I5 = I0
3 I7 = I3
4 goto 8
5 I6 = Square[ I7]
6 I8 = I4 + I6
7 I4 = I8
8 if[ ++ I7 < I5] goto 5
9 Return
"
*)
So my recommendation is to skip the check (what could generate the NaN in such a simple sum anyway?) or check for NaN values outside the compiled function.
MainEvaluate, I didn't notice any difference in execution speed on my system between:tot = Compile[{{x, _Real, 1}}, Total[x]] ; Timing[tot[RandomInteger[4, 100000000]]]andTiming[Total[RandomReal[4, 100000000]]]. I'm not sure why, butTotalapplied to integers seemed to be about 15% quicker than applied to reals. – image_doctor Apr 16 '12 at 09:47Totalwill be faster thanSum. Also, as a side note,AbsoluteTimingis better suited for thanTiming. – Apr 16 '12 at 10:09AbsoluteTiming. I'm not always sure about what I'm saying either :) Perhaps it was that in this context, withTotaland other 'simple' functions there is little if any advantage to using a compiled function, it may be thatTotalis already quite well optimised. I can see there is a difference between usingSumandTotal.Totalsums an existing list of numbers whereasSumneeds to construct an iteration across a range of not yet existing values, perhaps this means that they can't be compared directly. – image_doctor Apr 16 '12 at 13:55Totalis just a direct call to the kernel functionTotalAll, which is probably the same one used to implement the ordinaryTotalfor machine number inputs. In regard to whyTotalof integers is faster than reals: memory bandwidth. Reals are twice the size of integers. – Oleksandr R. Apr 16 '12 at 22:05