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.