映射2DArray时,F#性能更好 - > arraymodule.mapindexed

sch*_*opy 1 performance f#

在没有第三方的情况下处理这个2DArray的更高效的方法是什么?

#time
let ar = array2D[[5.0; 6.0; 7.0; 8.0]; [1.0; 2.0; 3.0; 4.0]]

[0..5000000]
let a2 = ar |> Array2D.mapi(fun rowi coli value -> (value + 1.6) * double(coli + 6) * double(rowi + 7))
Run Code Online (Sandbox Code Playgroud)

Tom*_*cek 7

如果你运行上面的代码,它需要大约0毫秒,所以我真的取决于你调用它的上下文.如果你只是循环运行它1M次,那么我的机器需要大约600ms:

for i in 0 .. 1000000 do
  let a2 = ar |> Array2D.mapi(fun rowi coli value -> 
    (value + 1.6) * double ((coli + 6) * (rowi + 7)))
  ()
Run Code Online (Sandbox Code Playgroud)

在这里,大部分时间都花在分配结果数组上 - 对于每次迭代,我们需要分配一个新的2D数组来存储结果.这为您提供了很好的功能属性(结果可以共享,因为它们没有发生变异),但这就是它需要更长时间的原因.

你可以使用一些变异并避免这种情况.这取决于上下文,所以这就是为什么你可能不会在这里得到一个有用的答案.

例如,在这个仿真的1M循环示例中,我可以只分配一个数组来存储结果,然后重复写入:

let res = ar |> Array2D.map id
for i in 0 .. 1000000 do
  for x in 0 .. ar.GetLength(0) - 1 do
    for y in 0 .. ar.GetLength(1) - 1 do
      res.[x, y] <- (ar.[x, y] + 1.6) * double ((x + 6) * (y + 7))
Run Code Online (Sandbox Code Playgroud)

这大约需要100毫秒,因此可以让您了解分配的成本.但是,如果它可以破坏你的程序,你不应该做这个改变,因为现在你正在使用可变数组......