Javascript 中数组的最大大小

上下文: 我正在构建一个小站点,它可以读取 RSS 提要,并在后台更新/检查提要。我有一个数组来存储要显示的数据,另一个数组存储已显示的记录的 ID。

问: 在事情变得缓慢或迟钝之前,一个数组可以在 Javascript 中保存多少条目。我没有对数组进行排序,而是使用 jQuery 的 inArray 函数进行比较。

该网站将保持运行和更新,浏览器不太可能重新启动/刷新那么频繁。

如果我应该考虑从数组中清除一些记录,那么在一个限制之后(比如100个项)删除一些记录的最佳方法是什么。

174126 次浏览

直到“它变得迟缓”之前的最大长度完全取决于您的目标机器和实际代码,因此您需要在那些平台上进行测试,以确定什么是可以接受的。

然而,根据 ECMA-262第5版规范,由于 ToUint32抽象操作,数组的最大长度受到一个无符号32位整数的约束,因此最长的数组可能有232-1 = 4.294,967,295 = 4.29亿个元素。

你可以试试这样来测试和修剪长度:

Http://jsfiddle.net/orolo/wjdxl/

var longArray = [1, 2, 3, 4, 5, 6, 7, 8];


if (longArray.length >= 6) {
longArray.length = 3;
}


alert(longArray); //1, 2, 3

它将非常依赖于浏览器。100件物品听起来不是一个很大的数字-我希望你可以比这个数字高得多。成千上万应该不是问题。可能存在的问题是总内存消耗。

我厚颜无耻地在内存中提取了一些相当大的数据集,虽然它确实变得缓慢,但是在数据集上进行了相当密集的计算,大约需要15 Mo 的数据。我怀疑您会遇到内存问题,除非您对数据和许多行进行了大量计算。使用不同的模拟结果集进行分析和基准测试将是评估性能的最佳选择。

我已经构建了一个性能框架,它可以操作数百万个数据集并绘制图表,即便如此,javascript 的计算延迟也只有几十毫秒。除非您担心超过数组大小限制,否则我认为您没有太多需要担心的。

不需要修剪数组,只需将其作为循环缓冲区(索引% maxlen)。这将确保它永远不会超出限制(实现循环缓冲区意味着,一旦到达终点,就再次绕到开始点——不可能超出数组的末尾)。

例如:

var container = new Array ();
var maxlen = 100;
var index = 0;


// 'store' 1538 items (only the last 'maxlen' items are kept)
for (var i=0; i<1538; i++) {
container [index++ % maxlen] = "storing" + i;
}


// get element at index 11 (you want the 11th item in the array)
eleventh = container [(index + 11) % maxlen];


// get element at index 11 (you want the 11th item in the array)
thirtyfifth = container [(index + 35) % maxlen];


// print out all 100 elements that we have left in the array, note
// that it doesn't matter if we address past 100 - circular buffer
// so we'll simply get back to the beginning if we do that.
for (i=0; i<200; i++) {
document.write (container[(index + i) % maxlen] + "<br>\n");
}

正如@maerics 所说,您的目标机器和浏览器将决定性能。

但是对于一些真实世界的数字,在我2017年的企业 Chromebook 上,运行操作:

console.time();
Array(x).fill(0).filter(x => x < 6).length
console.timeEnd();
  • x=5e4需要16毫秒,足以达到60帧每秒
  • x=4e6需要250毫秒,这是显而易见的,但不是大问题
  • x=3e7需要1300毫秒,这是相当糟糕的
  • x=4e7占用11000ms 并分配额外的2.5 GB 内存

所以大约3000万个元素是一个很难达到的上限,因为 javascript VM 在4000万个元素上跌落悬崖,可能会导致进程崩溃。


编辑: 在上面的代码中,我实际上用元素填充数组并循环它们,模拟应用程序可能对数组做的最小值。如果您只运行 Array(2**32-1) 你正在创建一个稀疏数组,那么它更接近于带有长度的空 JavaScript 对象,如 {length: 4294967295}。如果您真的尝试使用所有这40亿个元素,您肯定会使 javascript 进程崩溃。