Haskell数组与列表

Haskell数组与列表,haskell,Haskell,我在和Haskell和Project Euler玩第23个问题。在用列表解决它之后,我去了我看到一些数组工作的地方。这个解决方案比我的快得多。 所以问题来了。我什么时候应该在Haskell中使用数组?它们的性能是否优于列表?在哪些情况下?数组具有O(1)索引(这曾经是Haskell定义的一部分),而列表具有O(n)索引。另一方面,任何形式的数组修改都是O(n),因为它必须复制数组。 因此,如果要进行大量索引但很少更新,请使用数组。最明显的区别与其他语言相同:数组有O(1)查找,列表有O(n)。将

我在和Haskell和Project Euler玩第23个问题。在用列表解决它之后,我去了我看到一些数组工作的地方。这个解决方案比我的快得多。 所以问题来了。我什么时候应该在Haskell中使用数组?它们的性能是否优于列表?在哪些情况下?

数组具有O(1)索引(这曾经是Haskell定义的一部分),而列表具有O(n)索引。另一方面,任何形式的数组修改都是O(n),因为它必须复制数组。
因此,如果要进行大量索引但很少更新,请使用数组。

最明显的区别与其他语言相同:数组有O(1)查找,列表有O(n)。将某物附加到列表的开头(
)需要O(1);追加(
++
)需要O(n)

阵列还有其他一些潜在优势。可以使用未绑定的数组,这意味着条目只是连续存储在内存中,而没有指向每个条目的指针(如果我正确理解这个概念的话)。这有几个好处——占用更少的内存,可以提高缓存性能

修改不可变数组很困难——您必须复制整个数组,这需要O(n)。如果您使用可变数组,您可以在O(1)时间内修改它们,但您必须放弃使用纯功能解决方案的优势


最后,如果性能不重要,列表就更容易使用。对于少量数据,我总是使用列表

如果你在做大量的索引和更新,你可以

  • 使用
    Map
    s(或
    IntMap
    s),O(日志大小)索引和更新,对于大多数使用来说已经足够好了,代码很容易得到正确的结果
  • 或者,如果
    Map
    s速度太慢,请使用
    Data.Array.ST
    中的可变(未固定)数组(
    STUArray
    )或包中的STVectors;O(1)索引和更新,但代码更容易出错,而且通常不太好

对于特定用途,像
accumArray
这样的功能也提供了非常好的性能(在引擎盖下使用可变阵列).

我倾向于同意:除非你需要速度,否则使用列表。Haskell的内置列表非常友好,因为它能够在定义列表的两个构造函数上进行模式匹配:空列表和非空列表。@DanBurton:当然。另外,可能是因为我和Haskell同时学习了Scheme,所以我觉得列表更合适例如,在大多数语言中,使用列表编写递归函数要容易得多。