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

tro*_*lox 8 performance haskell

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

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

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

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

谢谢!

Don*_*art 11

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

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


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

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

  • 未装箱的,严格的字段
  • ST monad(安全访问原始内存)
  • 向量和修复库 - 高性能向量

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

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

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

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

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

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

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