Reputation: 750
I'm profiling a bit of F# code with VS2010, and the profiler shows that about 20% of the time is spent in 'JIT_ChkCastAny', but doesn't go so far as to point to the offending bit of code.
Does anyone know what kinds of things in F# compile into something that invokes this method?
Update: By commenting out chunks of code, I've narrowed it down to the following methods: Array.sumBy, Array.averageBy, Array.minBy, and Array.maxBy. In each case, the numerical type parameter is double, so why is the compiled code so slow?
Upvotes: 0
Views: 219
Reputation: 41290
Here is the implementation of Array.sum
in array.fs (similar for Array.sumBy
):
let inline sum (array: (^T)[] ) : ^T =
checkNonNull "array" array
let mutable acc = LanguagePrimitives.GenericZero< (^T) >
for i = 0 to array.Length - 1 do
acc <- Checked.(+) acc array.[i]
acc
It does use Checked.(+)
operator which has a lot of overheads. In case you wonder, the implementation of Checked.(+)
in prim-types.fs uses Reflection. And the JIT_ChkCastAny
term could result from using this Checked
module.
I did the following measurement to compare between Array.sum
and an implementation of sum using Array.fold
:
#time "on";;
let arr = [|for i in 1..10000000 -> float i|];;
arr |> Array.sum;;
arr |> Array.fold (+) 0.;;
The second version is indeed a magnitude faster than the first one. Therefore, if Array.sum
doesn't satisfy your requirement, you could use your own implementation of sum
.
Upvotes: 3