Performance 迭代最快的标准OCaml数据结构是什么?

Performance 迭代最快的标准OCaml数据结构是什么?,performance,data-structures,ocaml,Performance,Data Structures,Ocaml,我正在寻找一个通过封装的元素提供最快无序迭代的容器。换句话说,“添加一次,迭代多次” OCaml的标准模块中是否有一个速度足够快(这样进一步优化它就没用了)?或者某种第三方GPL就绪的 好吧,只有一个OCaml编译器,所以快速的概念或多或少是清楚的 …但在我看到几个答案后,似乎不是。当然,有很多数据结构允许通过大小为n的容器进行O(n)迭代。但我要解决的任务是其中之一,O(n)和O(2n)之间的差异很重要;-) 我还看到数组和列表提供了关于添加元素顺序的不必要信息,我不需要这些信息。也许在“函数

我正在寻找一个通过封装的元素提供最快无序迭代的容器。换句话说,“添加一次,迭代多次”

OCaml的标准模块中是否有一个速度足够快(这样进一步优化它就没用了)?或者某种第三方GPL就绪的

好吧,只有一个OCaml编译器,所以快速的概念或多或少是清楚的

…但在我看到几个答案后,似乎不是。当然,有很多数据结构允许通过大小为n的容器进行O(n)迭代。但我要解决的任务是其中之一,O(n)和O(2n)之间的差异很重要;-)

我还看到数组和列表提供了关于添加元素顺序的不必要信息,我不需要这些信息。也许在“函数世界”中存在这样的数据结构,可以用这些信息换取一点迭代速度


在C语言中,我会直接选择一个普通数组。问题是,我应该在OCaml中选择什么?

所有常见的数据结构在O(n)时间内都是可移植的,因此数据结构之间的差异将是恒定的(并且很可能不显著)


至少列表和数组允许迭代而不会产生很大的开销。我想不出哪种情况下速度不够快。

阵列-一个按顺序访问项目的线性内存块-最好地利用了CPU的一级数据缓存。

你不可能比内置阵列和列表做得更好,因为它们是用C手工编码的,除非绑定到自己的本机迭代器实现。数组的行为几乎与C中的数组(包含一系列元素值的连续分配内存块)完全相同,可能由于装箱而具有一些额外的指针间接性。列表的实现方式正是您所期望的:作为带有值和“next”指针的单元格。数组将为未绑定类型提供最佳的局部性(特别是
float
s,它有一个超级特殊的未绑定实现)

有关数组和列表实现的信息,请参阅和OCaml源代码中的文件
byterun/mlvalues.h
byterun/array.c
byterun/alloc.c

发问者:事实上,
数组
似乎是最快的解决方案。然而,它的表现仅比列表好7%。可能是因为数组元素的类型不够简单:它是代数类型
Hashtbl
表现比预期差4倍


所以,我将选择
Array
,我接受这个。很好。

要确定,您必须测量。根据编译器可能生成的机器指令,我将尝试一个数组,然后是一个列表

  • 访问数组元素需要边界检查、地址算法和加载

  • 访问列表头需要加载、空列表测试和已知编译时偏移量处的加载

哪个更快的细节可能取决于您的应用程序和机器上发生的其他情况。它们还取决于元素的类型;例如,如果它们是浮点数,
ocamlopt
可能足够聪明,可以生成一个非固定数组,这将为您节省一定程度的间接寻址

其他常见的数据结构,如哈希表或平衡树,通常需要在某个位置分配一些上下文来跟踪您所在的位置。对于数组,跟踪只需要一个整数索引;对于列表,跟踪需要一个指针。我认为这在另一个数据结构中是很难被击败的

最后请注意,可能只有一个OCaml编译器,但它有两个后端:字节码和本机代码。当然,如果您关心此级别的性能,那么您使用的是本机代码
ocamlopt
版本。对吧?


请进行测量并将结果编辑到您的问题中。

不要忘记
Bigarray
s,它们最接近C数组(只是一块平坦的内存),但不能包含任意OCaml值。还考虑切换边界检查(unSimultSe/GET)。当然,你应该先做个人简介。

这在C。。。在OCaml中它仍然是最快的吗?如果它是一个非固定数据类型(例如整数),数组值将存储在一个连续的内存块中。如果它是一个“装箱”数据类型(大多数是),那么它将是一个指针数组,因此您可能不会从列表中获得太多。1)学究式的O(n)和O(2n)之间没有区别。你说的是常数因子。2) 为元素选择任意顺序并修复它,就像在数组或列表中一样,这正是优化迭代的方式。您希望如何改进“增加索引/跟踪指针,从内存中获取”的迭代速度?1)是的,我说的是常数因子,因为我正在优化瓶颈;2) 我不知道如何改进,但这是数组和列表模块的工作方式吗?数组并不是说(虽然它可能是已知的)占用连续的内存。列表需要取消指针引用(慢?)。帕维尔:克里斯说的是你滥用了大O符号。他并不是说你不应该关心常数因子,只是说当你提到它们时,你应该在数学符号上更加清楚。@bcat,为什么这么严肃?;-)我的意思是,我假设每个阅读[ocaml]标签中的问题的人都知道它的意思,并且能够发现笑话,即使它们不是很好:——\n这是一个很老的问题,但由于某种原因,整个问题被移到了顶部。让我注意到列表不是用C手工编码的,它们被定义为一种常见的代数数据类型。为了方便起见,对一些语法糖进行模化,它只是
type'a list=Nil | C