Performance Haskell是否适合长时间运行的应用程序?
我认为Haskell是一种漂亮的语言,从基准测试来看,它的实现可以生成快速代码 但是,我想知道它是否适合于长时间运行的应用程序,或者在短时间运行的应用程序中追逐所有可能被忽略的由惰性引起的泄漏是否令人沮丧 与我的关切相呼应: 一旦有多个函数递归调用自身, 堆配置文件不再为您提供任何帮助,以确定 泄漏正在发生 (整个讨论似乎富有洞察力和坦率) 我个人对高性能计算很感兴趣,但我想服务器和HPC有这个共同的需求 如果Haskell适用于此类应用程序,是否有任何示例可以证明这一点,即Performance Haskell是否适合长时间运行的应用程序?,performance,haskell,memory-leaks,functional-programming,scientific-computing,Performance,Haskell,Memory Leaks,Functional Programming,Scientific Computing,我认为Haskell是一种漂亮的语言,从基准测试来看,它的实现可以生成快速代码 但是,我想知道它是否适合于长时间运行的应用程序,或者在短时间运行的应用程序中追逐所有可能被忽略的由惰性引起的泄漏是否令人沮丧 与我的关切相呼应: 一旦有多个函数递归调用自身, 堆配置文件不再为您提供任何帮助,以确定 泄漏正在发生 (整个讨论似乎富有洞察力和坦率) 我个人对高性能计算很感兴趣,但我想服务器和HPC有这个共同的需求 如果Haskell适用于此类应用程序,是否有任何示例可以证明这一点,即 需要运行数天或数周
更新:Haskell的Yesod web服务器框架,作为一个例子。我想知道是否有人在连续几天为请求提供服务后测试了它的内存使用情况。warp web服务器证明Haskell适合于长时间运行的应用程序
当Haskell应用程序出现空间泄漏时,可能很难找到原因,但一旦知道原因,通常很难解决(我曾经使用过的最难的修复方法是将
zip[1..]
应用到列表中,并从最后一个元素获取长度,而不是使用length
函数)。但在Haskell程序中,空间泄漏实际上非常罕见。通常,故意造成空间泄漏比修复意外泄漏更难。大多数长时间运行的应用程序都是请求驱动的。例如,HTTP服务器将所有瞬态数据与HTTP请求相关联。请求结束后,数据被丢弃。因此,至少对于那些长时间运行的应用程序,任何语言都不会有空间泄漏。在单个请求的上下文中泄漏所有您想要的内容。只要不创建对每个请求数据的全局引用,就不会泄漏
如果你改变了全局状态,所有的赌注都输掉了。由于许多原因,这是可以避免的,在这类应用中并不常见。我有一个用haskell编写的服务,它可以运行数月,没有任何haskell特定的问题。有一段时间,它工作了6个月,没有任何注意,但后来我重新启动它,以应用更新。它包含一个无状态HTTP API,但它也有状态完整的websockets接口,因此它保持长期生存状态。它的源代码是封闭的,所以我无法提供链接,但根据我的经验,haskell可以很好地用于长期运行的应用程序 懒惰对我来说不是问题,但那是因为我知道如何处理它。这并不难,但需要一些经验 此外,hackage上的库具有不同的质量,控制依赖关系是一件重要的事情。我尽量避免依赖性,除非它们确实是必要的,我检查了它们的大部分代码(除了一些广泛使用的软件包外,大多数都是核心库或Haskell平台的一部分,尽管我也检查了它们的代码——只是为了学习新东西) 尽管在某些情况下,GHC(最广泛使用的实现)不能很好地工作。当一个应用程序在内存中维护一个巨大的(大部分是只读的)状态时,我遇到了GC时间的问题(有一个)。而且很多稳定的指针可能会有问题(虽然我自己从未经历过)。大多数时候,通过仔细的设计,这样的情况很容易避免 实际上,对于长时间运行的应用程序来说,应用程序设计是最重要的。实现语言的作用不那么重要。这可能是我最近几年学到的最大的一课——软件设计非常重要,不同语言之间也没有太大区别 “空间泄漏”在语义上与任何语言中的任何其他类型的资源使用问题相同。在严格的语言中,GC倾向于分配和保留太多的数据(因为结构是严格的) 无论使用哪种语言,您都应该进行一些“磨合”,以随着时间的推移查找资源使用情况,Haskell也不例外 请参阅例如
xmonad
,它一次运行数月或数年。这是一个Haskell应用程序,堆使用量很小,我通过运行数周或数月来测试它,并在上面分析堆模式。这让我相信资源使用是稳定的
不过,归根结底,懒惰在这里是一个危险因素。使用资源监控工具和测试来衡量和验证您的资源期望。确实如此。有两种可能的空间泄漏: 堆上的数据。这里的情况与使用GC的其他语言没有什么不同。(对于那些不这样做的人,情况通常更糟——如果出现错误,进程可能会触及释放的内存,而不是增加内存使用量,反之亦然,从而严重崩溃。) 未经评估的恶棍。不可否认,一个人可以向自己的脚开枪, 当然,我们必须避免产生像
foldl(+)0
这样的巨大冲击的众所周知的情况。但要防止这一点并不困难,对于其他泄漏,我想说,当你习惯了它,它实际上比其他语言更容易
要么你