如何在Javascript中预先分配一个密集数组?

5
当使用new Array(size)构造函数时,如果size不是常量,在某些浏览器(至少在Chrome中)中,JS似乎会创建一个稀疏数组,导致访问速度比使用默认构造函数慢得多,如此处所示。
这正好与我的意愿相反:我预先分配了给定大小的数组,以避免动态重新分配,从而提高性能。有没有办法实现这个目标?
请注意,这个问题不是关于new Array(size)构造函数的歧义。我在这里发布了一些建议。

你的意思是,数组中不会有任何元素被推入或弹出吗? - thefourtheye
http://jsperf.com/pre-allocated-arrays/6 - Avinash Babu
2个回答

4

当预分配阈值为100000时,实际分配了1个空间,而当预分配阈值为99999时,仍然进行预分配,你可以看到这样做的速度更快。

http://jsperf.com/big-array-initialize/5


谢谢提供信息。难道没有办法修复吗?每个JS实例中都应该有一个简单的标志来覆盖该选项,不是吗?否则,如果服务器发送的数据恰好超过这个极其任意的数字,我会遇到麻烦,大麻烦。 - Domi
@Domi 这是应用程序代码没有验证用户输入的错误。阈值与V8垃圾收集器和堆的实现细节有关,因此无法使其更大。 - Esailija
你介意发布一个官方链接吗?另外,你是否知道如何在未来的JS版本中解决这个问题? - Domi
1
@Domi 这不是关于Javascript,而是V8。在该语言中,Javascript数组并不意味着任何形式的分配,甚至它们的背后都不一定是数组 - 实际上,如果您阅读Javascript数组规范,最明显的实现将是哈希表。最靠近官方链接的是您可以阅读的源代码https://github.com/v8/v8。 - Esailija

4
预分配与动态增长只是其中的一部分。对于预分配的数组,100,000刚好是V8决定给你一个缓慢(即“字典模式”)数组的阈值。
此外,按需增长数组并不会在每次添加元素时分配新的数组。相反,支持存储器以块增长(目前每次需要增长时大约增长50%,但这是一个随时间可能会改变的启发式算法)。
您可以在这里找到更多信息。感谢.. :)

我没有提出任何矛盾的声明。我提供的链接解释了动态分配如何将操作计数保持在O(1)。 - Domi
1
就像Esailija在这里为您所做的那样,您必须将任何复制的文字放在引用块中,以表明您并没有编写此内容。我看到的任何未遵循此规则的答案都将被删除。 - Brad Larson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接