【发布时间】:2020-07-30 17:22:15
【问题描述】:
所以我知道 Javascript 地图有一定数量的可以存储的键(大约 1670 万)。
我试图测试我是否可以(以一种非常丑陋的方式)从数组中删除最旧的元素。我注意到,无论我做什么,实际上并不是地图大小是一个限制因素,而是我所做的操作数量限制了我。
下面是示例代码:
const map = new Map();
let i = 0;
while (true) {
i++;
set(i, i);
if (i % 1000 === 0)
console.log('INSERTED: ', i, 'KEYS', 'MAP SIZE :', map.size);
}
function set(key, value) {
if (map.size > 16770000) {
Array.from(map.keys()).slice(0, 10000).forEach(key => map.delete(key));
console.log('DELETED, current map size:', map.size);
}
try {
map.set(key, value);
} catch (e) {
console.log('MAP SIZE:', map.size, 'INSERTED:', key);
throw e;
}
}
当您运行 sn-p 时,只需检查您的控制台。您应该注意到最后(抛出异常时)您将获得 Map Size 和 INSERTED。 Map Size 将是一个变量(取决于您删除的元素数量,在本例中为 10000),但 INSERTED 将始终是相同的值。那么,如果我没有达到地图的极限怎么办......我以某种方式达到了极限。这是我缺少的某种参考问题吗?
编辑:正如@CRice 所提到的,如果您将删除的项目增加到大约 10,000,000 个,那么这个循环似乎会永远持续下去。
编辑 2:这是来自 V8 开发人员之一的回答,谈到 16.7M 键的限制:https://stackoverflow.com/a/54466812/5507414
编辑 3:见答案:https://stackoverflow.com/a/63234302/5507414。我们仍然需要 V8 开发人员或对引擎有进一步了解的人来澄清这一点。
【问题讨论】:
-
不确定我是否理解这个问题,你能澄清一下吗?我在控制台中看到最后地图的大小为 16767216(如您所说,约为 16.7M)。最后插入的密钥是
16777217,比最大地图大小高 10000,日志显示您在此之前删除了 10000 个密钥,所以对我来说一切都很好...... -
好吧,如果我删除了 10000 个键,那是不是意味着我应该可以再设置 10000 个键?问题是我不能。插入的最后一个键实际上应该多 10000 个。但事实并非如此。如果你得到 sn-p 并把它改成不是 10000 而是 20000 你会看到最后插入的键仍然是 16777217。为什么我删除键时没有更多空间?
-
是的,我现在明白你的意思了。这很好奇。我还注意到,如果您大大增加已删除项目的数量(我尝试了 10000000),那么它会永远继续插入/删除循环。我也对这里发生的事情感兴趣。
-
好问题和好答案。对所有内容都投了赞成票。请您也添加一个指向 16.7M 限制的引用。
-
@x00 我在答案中添加了引用;这个解释了地图限制:stackoverflow.com/a/54466812/5260917
标签: javascript arrays maps v8