为什么Haskell的默认字符串实现是字符链表?

时间:2012-12-13 17:41:41

标签: string performance haskell linked-list

Haskell的默认String实现在速度和内存方面效率都不高,这一点众所周知。据我所知,[] lists一般在Haskell中实现为单链表和大多数小/简单数据类型(例如Int),但这似乎不是一个好主意,但是对于String来说,这似乎完全矫枉过正。关于这个问题的一些意见包括:

Real World Haskell

  

在像这样的简单基准测试中,即使用Python等解释语言编写的程序也可以胜过使用String一个数量级的Haskell代码。

Efficient String Implementation in Haskell

  

由于String只是[Char],这是Char的链接列表,这意味着字符串具有较差的引用局部性,并且再次意味着字符串在内存中相当大,至少它是N *(21位+ Mbits) )其中N是字符串的长度,M是指针的大小(...)。字符串不太可能被编译器优化为循环等。

我知道Haskell有几种不同风格的ByteString s(和Array s)并且它们可以很好地完成工作,但我希望默认实现是最有效的。

TL; DR:为什么Haskell的默认String实现是单链表,即使它非常低效且很少用于真实世界的应用程序(除了非常简单的应用程序)?有历史原因吗?实施起来更容易吗?

3 个答案:

答案 0 :(得分:19)

  

为什么Haskell的默认String实现是单链表

因为单链接列表支持:

  • 通过模式匹配进行归纳
  • 具有有用的属性,例如Monad,Functor
  • 具有适当的参数多态性
  • 自然是懒惰的

所以String[Char](unicode points)意味着符合语言目标的字符串类型(截至1990年),并且基本上是“免费”使用列表库。

总之,从历史上看,语言设计者对设计良好的核心数据类型感兴趣,而不是文本处理的现代问题,所以我们有一个优雅,易于理解,易于教授的String类型,不是一个unicode文本块,并且不是一个密集,打包,严格的数据类型。

答案 1 :(得分:12)

效率只是衡量抽象的一个轴。虽然列表对于text-y操作来说效率非常低,但是它们非常方便,因为有很多列表操作以多态方式实现,当专门用于[Char]时有很多有用的解释,所以你在库实现中得到了很多重用并且在用户的大脑中。

目前尚不清楚,根据我们目前的经验水平,今天的语言是否正在设计中,同样的决定也是如此;但是,在经验可用之前,并不总是能够做出完美的决定。

答案 2 :(得分:4)

此时,它可能是历史性的:使ByteString这样的效率如此高效的优化是最近的,而[Char]早于它们都是多年。