对于非常有状态的游戏/模拟,Haskell状态与C ++的比较效率如何?

时间:2013-03-06 17:03:05

标签: performance haskell

我似乎无法找到有关该主题的任何结论性信息。那里有很多Haskell游戏实现,但我发现的是小游戏,目前还不清楚他们的方法是否扩展。同样地,关于在Haskell程序中使用状态(主要使用State monad)有很多信息,但很少关于这些方法的效率是否与命令式语言中的状态相当。

我正在使用一个具有极其简单图形的模拟器,这使得在Haskell中进行开发非常适合我。但是,我想尽可能多地模拟实体,这意味着效率非常重要。为了使用Haskell,我会接受一个小的性能降低,但我担心这个模拟的状态性质会使Haskell代码比我的其他选择C ++慢一个数量级。

正如标题所述,Haskell如何比较这种类型的应用程序?除了链接到已实现的状态高性能Haskell程序之外,对Haskell中使用方法的建议将不胜感激。

如果需要一个更具体的例子来说明我需要如何维护状态,我可以提供一个,但只要考虑在每次迭代中大量改变的大量坐标就足够了。

谢谢!

1 个答案:

答案 0 :(得分:11)

目前您的问题无法直接回答。

TL; DR:理论上没有理由说明为什么会遇到性能问题。当然不知道有什么理由让“一个数量级”的性能更差。但是,除非你有一个具体的场景,除了广泛的陈述之外,很难做出任何其他的事情。


Haskell可以像C ++一样访问裸内存并随机播放。因此,没有理论上的“数量级慢”需要关注。实际上,如果你希望将状态表示为可变的内存块,或堆栈分配的帧,或者其他什么,Haskell(GHC实现)支持这一点 - 毕竟有一些用Haskell编写的操作系统。

在这方面有用的一些习语和库:

  • 未装箱的严格字段
  • ST monad(安全访问原始内存)
  • vector和repa库 - 高性能载体

除非您正在编程设备驱动程序,否则很可能您不需要绝对低级别控制。

只要您的算法合理,您就可以了。

Haskell的GHC实现具有非常快速的分配(凹凸指针),使得不可变数据便宜。使用不可变数据没有固有的损失,您可以更轻松地进行并行化,并且代码更易于维护。所以如果可以的话,坚持使用Haskell成语。

  

我想尽可能多地模拟实体,这意味着效率非常重要。

GHC有一个非常有效的分配器和垃圾收集器,对象很便宜且开销很低 - 假设你使用合理的数据表示 - 所以我认为没有问题。例如。在基准测试游戏中,二元树基准测试分配器性能 - C++ and GHC Haskell are tied在编写此微测试时。{/ p>

最终,从根本上使用Haskell不会受到任何惩罚。您可以在必要时使用命令式算法 - 可能您不需要。只是不要犯下使用朴素算法的错误(比如使用不可变列表代替可变数组)。这是迄今为止最大的风险 - 作为新用户,您可能会使用效率低下的方法 - 寻求帮助和简介:)

另外,10年前新的Haskell用户编写了Frag,其性能完全可以接受。 GHC现在也更聪明了......