Haskell实时更新和查找性能

Gre*_*efe 10 arrays performance profiling haskell mutable

我正在写一个玩游戏的ai(aichallenge.org - Ants),它需要大量更新,并引用数据结构.我已经尝试了数组和地图,但基本问题似乎是每次更新都会创建一个新值,这会让它变慢.如果您花费超过一秒钟来进行移动,游戏会引导您,因此应用程序将被视为"硬实时".是否有可能在Haskell中具有可变数据结构的性能,或者我应该学习Python,还是在OCaml中重写我的代码?

我完全改写了蚂蚁"初学者包".从阵列更改为地图,因为我的测试显示地图更新速度更快.

我运行了地图版本并进行了分析,结果显示仅有20%的时间是由地图更新单独进行的.

这是一个简单的演示,说明阵列更新的速度有多慢.

slow_array =
    let arr = listArray (0,9999) (repeat 0)
        upd i ar = ar // [(i,i)]
    in  foldr upd arr [0..9999]
Run Code Online (Sandbox Code Playgroud)

现在评估slow_array!9999需要将近10秒!虽然一次应用所有更新会更快,但该示例模拟了每回合必须更新阵列的真正问题,并且最好每次在计划下一轮时选择移动.


感谢nponeccop和Tener参考矢量模块.以下代码等同于我的原始示例,但运行时间为0.06秒而不是10秒.

import qualified Data.Vector.Unboxed.Mutable as V

fast_vector :: IO (V.IOVector Int)
fast_vector = do
  vec <- V.new 10000
  V.set vec 0
  mapM_ (\i -> V.write vec i i) [0..9999]
  return vec

fv_read :: IO Int
fv_read  = do
  v <- fast_vector
  V.read v 9999
Run Code Online (Sandbox Code Playgroud)

现在,将其纳入我的蚂蚁代码......

npo*_*cop 12

首先,想想你是否可以改进你的算法.另请注意,默认Ants.hs值并非最佳,您需要自己滚动.

其次,您应该使用分析器来查找性能问题的位置,而不是依赖于挥手.Haskell代码通常比Python快得多(快10到30倍,你可以查看语言Shootout进行比较),即使是功能数据结构,所以你可能做错了.

Haskell 很好地支持可变数据.请参阅ST(状态线程)和库的可变数组ST.另外看看矢量包.最后,您可以使用数据并行haskell,haskell-mpi或其他并行方式来加载所有可用的CPU内核,甚至可以在多台计算机上分配工作.

您使用的是编译代码(例如cabal buildghc --make)还是使用runhaskellghci?后者是字节码解释器,并且创建比本机代码编译器慢得多的代码.请参阅Cabal参考 - 它是构建应用程序的首选方法.

还要确保已打开优化(-O2其他标志).请注意,-Ovs -O2可以产生影响,并尝试使用不同的后端,包括新的LLVM后端(-fllvm).