- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在学习 Haskell 并阅读了几篇关于 Haskell 列表和(插入您的语言)数组的性能差异的文章。
作为一名学习者,我显然只是使用列表,甚至没有考虑性能差异。
我最近开始调查并发现 Haskell 中有许多可用的数据结构库。
有人可以在不深入了解数据结构的计算机科学理论的情况下解释列表、数组、向量、序列之间的区别吗?
另外,是否有一些常见的模式,您会使用一种数据结构而不是另一种数据结构?
是否有任何其他形式的数据结构我遗漏了并且可能有用?
最佳答案
列出摇滚
到目前为止,Haskell 中对顺序数据最友好的数据结构是 List
data [a] = a:[a] | []
foldr
、
map
、
filter
)。列表是持久的,也就是纯函数式的,这非常好。 Haskell 列表并不是真正的“列表”,因为它们是共同归纳的(其他语言称为这些流),因此诸如
ones :: [Integer]
ones = 1:ones
twos = map (+1) ones
tenTwos = take 10 twos
(!!)
需要 ϴ(k) 时间,这很烦人。此外,追加可能很慢
++
,但是 Haskell 的惰性求值模型意味着这些可以被视为完全摊销,如果它们发生的话。
std::vector
比我所知道的任何纯链表数据结构都具有更快的“snoc”(将对象放在最后),尽管这不是一个持久性数据结构,不如 Haskell 的列表那么友好。
Data.Sequence
内部基于
finger trees (我知道,你不想知道这一点)这意味着它们有一些不错的特性
Data.Sequence
是一个完全持久化的数据结构。 Data.Sequence
最多是一个常数较慢。 Data.Sequence
对数据局部性问题没有太大作用,仅适用于有限集合(它不如列表懒惰)
Data.Vector
包以更高级别和更清晰的 API 提供了所有数组的优点。除非你真的知道你在做什么,否则如果你需要类似数组的性能,你应该使用这些。当然,一些警告仍然适用——像数据结构这样的可变数组在纯粹的惰性语言中表现不佳。尽管如此,有时您还是想要 O(1) 的性能,而
Data.Vector
给你一个可用的包。
[Char]
前奏曲别名为
String
.
Char
列表很方便,但运行速度往往比 C 字符串慢 20 倍,所以可以随意使用
Data.Text
或非常快
Data.ByteString
.我确定还有其他面向序列的库,我现在没有想到。
toList
与任何其他数据结构一起使用。他们附带的功能。在一个更好的世界中,前奏将完全参数化它使用的容器类型,但目前
[]
乱扔标准库。因此,(几乎)在任何地方都使用列表绝对没问题。
Prelude.map ---> Prelude.fmap (works for every Functor)
Prelude.foldr/foldl/etc ---> Data.Foldable.foldr/foldl/etc
Prelude.sequence ---> Data.Traversable.sequence
etc
Data.Traversable
定义了一个 API,该 API 或多或少适用于任何“类似列表”的事物。
Data.Vector
对比
Data.Sequence
.数组和向量提供极快的索引和切片操作,但基本上是 transient (命令式)数据结构。纯函数式数据结构,如
Data.Sequence
和
[]
让有效地从旧值生成新值,就像您修改了旧值一样。
newList oldList = 7 : drop 5 oldList
oldList
非常长,这种“修改”会非常快。同样
newSequence newValue oldSequence = Sequence.update 3000 newValue oldSequence
newValue
的新序列因为代替了它的 3000 个元素。同样,它不会破坏旧序列,它只是创建一个新序列。但是,它非常有效地执行此操作,取 O(log(min(k,k-n)) 其中 n 是序列的长度,k 是您修改的索引。
Vectors
轻松做到这一点和
Arrays
.它们可以被修改,但那是真正的命令式修改,因此不能在常规 Haskell 代码中完成。这意味着在
Vector
中的操作进行修改的软件包,如
snoc
和
cons
必须复制整个向量所以取
O(n)
时间。唯一的异常(exception)是您可以在
Vector.Mutable
中使用可变版本(
ST
)。 monad(或
IO
)并像使用命令式语言一样进行所有修改。完成后,您可以“卡住”您的向量以转换为您想要与纯代码一起使用的不可变结构。
Data.Sequence
如果列表不合适。使用
Data.Vector
仅当您的使用模式不涉及进行大量修改时,或者您需要在 ST/IO monad 中具有极高的性能时。
ST
monad 让你感到困惑:更有理由坚持纯粹的快速和美丽
Data.Sequence
.
关于Haskell:列表、数组、向量、序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9611904/
我正在尝试创建一个包含 int[][] 项的数组 即 int version0Indexes[][4] = { {1,2,3,4}, {5,6,7,8} }; int version1Indexes[
我有一个整数数组: private int array[]; 如果我还有一个名为 add 的方法,那么以下有什么区别: public void add(int value) { array[va
当您尝试在 JavaScript 中将一个数组添加到另一个数组时,它会将其转换为一个字符串。通常,当以另一种语言执行此操作时,列表会合并。 JavaScript [1, 2] + [3, 4] = "
根据我正在阅读的教程,如果您想创建一个包含 5 列和 3 行的表格来表示这样的数据... 45 4 34 99 56 3 23 99 43 2 1 1 0 43 67 ...它说你可以使用下
我通常使用 python 编写脚本/程序,但最近开始使用 JavaScript 进行编程,并且在使用数组时遇到了一些问题。 在 python 中,当我创建一个数组并使用 for x in y 时,我得
我有一个这样的数组: temp = [ 'data1', ['data1_a','data1_b'], ['data2_a','data2_b','data2_c'] ]; // 我想使用 toStr
rent_property (table name) id fullName propertyName 1 A House Name1 2 B
这个问题在这里已经有了答案: 关闭13年前。 Possible Duplicate: In C arrays why is this true? a[5] == 5[a] array[index] 和
使用 Excel 2013。经过多年的寻找和适应,我的第一篇文章。 我正在尝试将当前 App 用户(即“John Smith”)与他的电子邮件地址“jsmith@work.com”进行匹配。 使用两个
当仅在一个边距上操作时,apply 似乎不会重新组装 3D 数组。考虑: arr 1),但对我来说仍然很奇怪,如果一个函数返回一个具有尺寸的对象,那么它们基本上会被忽略。 最佳答案 这是一个不太理
我有一个包含 GPS 坐标的 MySQL 数据库。这是我检索坐标的部分 PHP 代码; $sql = "SELECT lat, lon FROM gps_data"; $stmt=$db->query
我需要找到一种方法来执行这个操作,我有一个形状数组 [批量大小, 150, 1] 代表 batch_size 整数序列,每个序列有 150 个元素长,但在每个序列中都有很多添加的零,以使所有序列具有相
我必须通过 url 中的 json 获取文本。 层次结构如下: 对象>数组>对象>数组>对象。 我想用这段代码获取文本。但是我收到错误 :org.json.JSONException: No valu
enter code here- (void)viewDidLoad { NSMutableArray *imageViewArray= [[NSMutableArray alloc] init];
知道如何对二维字符串数组执行修剪操作,例如使用 Java 流 API 进行 3x3 并将其收集回相同维度的 3x3 数组? 重点是避免使用显式的 for 循环。 当前的解决方案只是简单地执行一个 fo
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我有来自 ASP.NET Web 服务的以下 XML 输出: 1710 1711 1712 1713
如果我有一个对象todo作为您状态的一部分,并且该对象包含数组列表,则列表内部有对象,在这些对象内部还有另一个数组listItems。如何更新数组 listItems 中 id 为“poi098”的对
我想将最大长度为 8 的 bool 数组打包成一个字节,通过网络发送它,然后将其解压回 bool 数组。已经在这里尝试了一些解决方案,但没有用。我正在使用单声道。 我制作了 BitArray,然后尝试
我们的数据库中有这个字段指示一周中的每一天的真/假标志,如下所示:'1111110' 我需要将此值转换为 boolean 数组。 为此,我编写了以下代码: char[] freqs = weekday
我是一名优秀的程序员,十分优秀!