Java的ArrayList / Scala的ArrayBuffer可能有哪些改进?

时间:2011-05-31 12:00:19

标签: java arrays performance scala buffer

目前,“增长”算法指出支持Array / ArrayList的{​​{1}}对于请求的操作而言太小,并将内容复制到更大数组的开头

jsuereth this thread的评论中解释得非常好:

  

ArrayBuffer很适合追加但是   不如前期好。 Java的   ArrayList实际上会尝试   摊销费用也可以预先支付,   让我的表现略胜一筹   意见。可能是ArrayBuffer   如果你只是追加,那就足够了   列表和索引元素。

基于以下假设将来可能更频繁地调用此操作,使旧内容的位置取决于最后一个操作是不是一个很好的增强?

予。 E:

  • 如果ArrayBuffer需要更大的数组,请将现有内容复制到新数组的前面:

    append
  • 如果[x|x|x|x|x|x] | v [x|x|x|x|x|x| | | | | ] 需要更大的数组,请将现有内容复制到新数组的后面:

    prepend

这是否会解决prepend的性能问题,同时通常会使算法更适应使用模式? (最坏的情况可能是附加/增加大量的东西......)

在增长底层结构时,是否还有其他数据结构已考虑最后一项操作?

4 个答案:

答案 0 :(得分:4)

也许你需要的是ArrayDeque。这有一个O(1)操作用于追加和前置(除非容量改变)

这个数组有一个headtail的索引,允许它写入开始或结束位置,而不必向下/向上移动所有条目。

答案 1 :(得分:3)

在一般意义上,MOST预定义结构和算法基于最常见用例的一些假设。由于无法创建涵盖所有可能情景的“通用”实现,因此总会出现一些外部情况,即方法不是最优的。

如果您的特定用例对性能至关重要,这是一个问题,我的建议是根据您的使用情况创建自己的Array实现。但要注意次优化魔鬼。实际上很少值得增加维护成本来节省那些奇怪的CPU周期或内存字节。

答案 2 :(得分:2)

您可以将ArrayDeque用于具有快速前置的阵列支持的数据结构。

答案 3 :(得分:2)

如果您不打算进行大量的查找,只是进行线性遍历,那么请转到UnrolledBuffer - 展开的链表实现。否则,Vector及其+:应该是一种有效的选择。