Javascript中数组的最大大小

Javascript中数组的最大大小,javascript,arrays,Javascript,Arrays,上下文:我正在构建一个小站点,它读取rss提要,并在后台更新/检查提要。我有一个数组存储要显示的数据,另一个数组存储已显示记录的ID 问题:在Javascript中一个数组可以容纳多少项,然后事情开始变得缓慢或迟钝。我没有对数组进行排序,而是使用jQuery的inArray函数进行比较 该网站将保持运行状态,并且不太可能经常重新启动/刷新浏览器 如果我应该考虑从数组中清除一些记录,那么在限制后删除一些记录(例如100项)的最佳方法是什么。直到“它变慢”的最大长度完全取决于您的目标计算机和实际代码

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

问题:在Javascript中一个数组可以容纳多少项,然后事情开始变得缓慢或迟钝。我没有对数组进行排序,而是使用jQuery的inArray函数进行比较

该网站将保持运行状态,并且不太可能经常重新启动/刷新浏览器

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

直到“它变慢”的最大长度完全取决于您的目标计算机和实际代码,因此您需要在该(那些)平台上进行测试,以确定哪些是可接受的


但是,根据ECMA-262第5版规范,由于ToUint32抽象运算,数组的最大长度受无符号32位整数的限制,因此最长的数组可能包含232-1=4294967295=42.9亿个元素。

您可以尝试以下方法来测试和修剪长度:

var longArray=[1,2,3,4,5,6,7,8];
如果(longArray.length>=6){
longArray.length=3;
}

警报(长阵列)//1、2、3将非常依赖于浏览器。100件听起来不是一个很大的数字——我希望你能比这个数字高很多。数千人不应该是个问题。可能存在的问题是总内存消耗。

我无耻地在内存中提取了一些相当大的数据集,尽管数据集确实变得很慢,但在数据集上进行了相当密集的计算,可能需要15个月的数据。我怀疑你会遇到内存问题,除非你对数据和许多行有密集的计算。使用不同的模拟结果集进行评测和基准测试将是评估性能的最佳选择。

我构建了一个性能框架,可以处理和绘制数百万个数据集,即使如此,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");
}
var容器=新数组();
var maxlen=100;
var指数=0;
//“存储”1538项(仅保留最后的“maxlen”项)

对于(var i=0;i,如@maerics所说,您的目标机器和浏览器将决定性能

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

console.time();
Array(x).fill(0).filter(x => x < 6).length
console.timeEnd();
console.time();
数组(x).fill(0).filter(x=>x<6).length
console.timeEnd();
  • x=5e4
    需要16ms,足够60fps
  • x=4e6
    需要250毫秒,这很明显,但不是什么大问题
  • x=3e7
    需要1300ms,这非常糟糕
  • x=4e7
    需要11000ms,并额外分配2.5GB内存
因此,大约3000万个元素是一个很难的上限,因为javascript虚拟机在4000万个元素的情况下跌入悬崖,可能会使进程崩溃



编辑:在上面的代码中,我实际上是在数组中填充元素并循环,模拟应用程序可能希望对数组执行的最小操作。如果您只运行
array(2**32-1)
,则更接近于具有长度的空JavaScript对象,如
{length:4294967295}
。如果你真的试图使用这40亿个元素,你肯定会使javascript进程崩溃。

浏览器从工具栏泄漏内存的问题可能会比从JS代码泄漏内存的问题更多。:)Firefox 4我将手指指向你。你多久检查一次数组(ex 2s间隔)?什么构成迟滞(ex>500ms)?您的阵列的数量级是多少(例如,数千、数百万、数十亿)?使用我将每分钟检查和更新阵列进行基准测试。是的,这将是一个性能打击,开始影响加载和检查,以及页面上的其他动画,很难定义抱歉@谢谢你的链接,看起来该网站将成为我的新好友:)@Barkermn01:ECMA-262第5版规范使用抽象操作ToUint32在任何修改数组长度的操作中检查数组的长度,因此我认为机器(或web浏览器)的底层架构是不相关的。hrm很好,只是读到一篇文章说,一些64位浏览器是毫无意义的,那么,@Barkermn01,64位浏览器还有很多其他的改进。记住,作为一个javascript解释器并不是浏览器唯一要做的事情。Wowzer不会期望它有那么高。好的,很好,我想我会没事的!实际上,一个数组最多可以有4294967295(2^31-1)个元素。谢谢,我最终使用了slice,因为我需要从数组的开头开始修剪。这是一个聪明的想法,但这样做可能会覆盖数据,混淆索引,并可能导致奇怪的行为。这个想法是为了实现一个环形缓冲区,所以是的-你故意“忘记”旧数据(这就是环形缓冲区的用途)这就是提问者所要求的。我只是无聊地四处点击,然后找到了这个答案。我喜欢这种根据需要覆盖索引的技术。我在节点v12.17.0上试过,英特尔Core i7,1亿个元素占用了2.3GB内存,占用了约2秒,CPU约12%,什么都没有崩溃。@Slawomerbrys你运行了什么?你最终会撞上悬崖吗?在节点v15.3.0和核心i9的macbook上,我看到了相同的悬崖:
time node-e“console.log(Array(