Performance 为什么这段代码没有更快?
我制作了一段java代码的“副本”,运行时间约为400毫秒()。我的F#版本使用了Performance 为什么这段代码没有更快?,performance,f#,Performance,F#,我制作了一段java代码的“副本”,运行时间约为400毫秒()。我的F#版本使用了Parallel.ForEach,我也尝试了PSeq,但没有一个版本的速度超过7秒 这并不是说我必须让我的代码比我复制的代码快,而是我真的很想知道在F#中这样的示例计算中可以做些什么来提高性能 您需要使用内置的数组初始化代码,因为在本例中,当前数组初始化需要很长时间。因此,更换线路 let bits = [| for i in 1 .. ((n+1)*(n+1)) -> 0 |] 用线 let bits =
Parallel.ForEach
,我也尝试了PSeq
,但没有一个版本的速度超过7秒
这并不是说我必须让我的代码比我复制的代码快,而是我真的很想知道在F#中这样的示例计算中可以做些什么来提高性能
您需要使用内置的数组初始化代码,因为在本例中,当前数组初始化需要很长时间。因此,更换线路
let bits = [| for i in 1 .. ((n+1)*(n+1)) -> 0 |]
用线
let bits = Array.init ((n+1)*(n+1)) (fun _ -> 0)
您应该可以获得与Java代码相当的性能
更新:正如John Palmer所建议的,Array.zeroCreate
将使数组初始化为零的速度更快。因此,如果只需要将数组初始化为零,而不计算任何初始值,那么使用
let bits = Array.zeroCreate ((n+1)*(n+1))
更新:之前已经解释了它如此之快的原因。简短摘要:它使用适当的IL字节码命令newarr
进行初始化,而初始化又在.Net运行时进行了优化,速度非常快Array.init
比直接的“手动”初始化快,因为它调用zeroCreateUnchecked
初始化数组,然后在已经初始化的数组上运行初始化函数
如果您想知道代码在哪里,那么下面是链接:它们依次调用。我认为理论上的答案可以解释为什么Java速度更快: 在F#中使用该库可能会更快(或者至少“承诺”会更快) 资料来源如下: 或者在nuget: 希望您能够比较Java苹果和F#苹果(确定不是苹果,而是streams;-)
它也不会改变你的代码太多,我想…只是使用
并行。ForEach
并不自动意味着更好的性能。。。线程/任务初始化可能会导致性能下降,这可能比循环中的实际操作花费更长的时间。@Matze,那么您有什么建议来改进它呢?我确实认为应该有可能接近链接到java代码的性能。谢谢先生。我不知道Array.init的速度要快得多。您知道它更快吗?使用Array.zeroCreate
let bits = Array.init ((n+1)*(n+1)) (fun _ -> 0)
let bits = Array.zeroCreate ((n+1)*(n+1))