2012-01-26 54 views
0

我用VS2010分析了一些F#代码,并且分析器显示大约20%的时间花在了'JIT_ChkCastAny'上,但是没有指出这个问题。一点代码。F#分析和JIT_ChkCastAny

有谁知道F#中有什么东西编译成调用这个方法的东西?

更新:通过评论大块的代码,我已经缩小到下列方法: Array.sumBy,Array.averageBy,Array.minBy和Array.maxBy。在每种情况下,数字类型参数都是双倍的,那为什么编译后的代码很慢呢?

+2

如果没有代码片段或者您所描述的屏幕截图,说什么都太难了? – pad

+1

如果您想要提高代码性能方面的一些帮助,请发布代码片段来说明问题。 – pad

回答

3

这里是Array.sumarray.fs实施办法(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 

它使用Checked.(+)运营商里面有很多开销。如果您想知道,在prim-types.fs 中使用 Checked.(+)的实现使用了反射 。并且JIT_ChkCastAny术语可能来自使用此Checked模块。

我做了以下的测量Array.sum和使用Array.fold总和的实现之间进行比较:

#time "on";; 
let arr = [|for i in 1..10000000 -> float i|];; 
arr |> Array.sum;; 
arr |> Array.fold (+) 0.;; 

第二个版本的确是一个幅度比第一个快。因此,如果Array.sum不能满足您的要求,您可以使用自己的sum实现。

+2

我很确定'GenericZero'根本没有任何开销。有趣的是,内置累加功能全部被检查;我会希望他们没有被选中,并可能有替代的检查实现。 : - [ – ildjarn

+1

也可以提供未经检查的版本,并让用户自行决定。 – pad

+0

感谢您的全面回答!我知道通用零点,但没有意识到检查过的操作员速度要慢得多。 – mpeac