【发布时间】:2020-01-30 15:08:22
【问题描述】:
在 JS 数组的情况下,可以创建一个具有预定义长度的数组。如果我们将长度传递给构造函数,例如new Array(itemCount),JS 引擎可以为数组预先分配内存,因此在向数组添加新项目时不需要重新分配内存。
是否可以为Map 或Set 预先分配内存?它不像数组那样接受构造函数中的长度。如果您知道一个映射将包含 10 000 个项目,那么分配一次内存应该比多次重新分配内存要高效得多。
这是关于数组的same question。
在 cmets 中有讨论,预定义的数组大小是否对性能有影响。我创建了一个simple test 来检查它,结果是:
- Chrome - 使用预定义大小填充数组的速度大约快 3 倍
- Firefox - 没有太大区别,但是预定义长度的数组要快一点
- 边缘 - 填充预定义大小的数组大约快 1.5 倍
有一个建议是创建条目数组并将其传递给地图,因此地图可以从数组中获取长度。我也创建了这样的test,结果是:
- Chrome - 构建接受条目数组的地图的速度大约慢 1.5 倍
- Firefox - 没有区别
- Edge - 将条目数组传递给 Map 构造函数的速度大约快 1.5 倍
【问题讨论】:
-
“JS 引擎可以为数组预先分配内存” 真的可以吗?数组可以包含异构数据。虽然我不得不承认对浏览器引擎没有洞察力,但看起来在那里可以做的事情并不多。但当然,我可能完全错了。编辑:我查看了链接的问题,但我仍然怀疑性能差异实际上是由于内存分配还是其他原因。
-
@ASDFGerte 你呢? Hashmaps 也有大小,增长它们比增长数组更复杂......
-
我相信以前的 cmets 对
new Array(size)为数组中的元素分配内存的想法感到不满。它没有。它为将放置数组元素的“槽”分配内存。这确实会为阵列带来性能优势。Maps 和Sets 使用不同的算法来存储他们的数据,如果我没记错的话,可能不会获得相同的性能优势。 -
调用
new Map(array)可以将arrays 的长度作为大小的谓词。不确定是不是。 -
@JonasWilms 对实际发生的事情的回答将针对许多与实现相关的事情。有时我只是在戳戳,不管这是否有意义,开始深入了解所需的细节。我知道,哈希图也在增长。该评论不应暗示他们没有。异构数据结构,以及引擎如何对大量参数进行猜测,例如大小,或者它们将包含什么内容,以及将在内部分配什么结构,是一个很大的话题。
标签: javascript performance ecmascript-6