gpt4 book ai didi

Javascript 对象与 map 性能(Chrome、V8、Node JS)

转载 作者:行者123 更新时间:2023-12-03 12:17:42 24 4
gpt4 key购买 nike

如果我需要在大型数据集(> 1000 个对象)中通过字符串键进行随机查找,我正在尝试了解是否使用 JS 对象或 Map。

我编写了一个简单的基准测试 http://jsperf.com/javascript-objects-vs-map-performance,结果表明在 Chrome (V8) 中,对象的性能优于 map 大约 2 倍。但是,我检查了其他浏览器,结果却相反。为什么它们在各种浏览器/引擎中如此不同?

我还在 Node.JS 中编写了一个类似的测试,但我看不到类似的结果(测试用例 6 比测试用例 4 花费的时间要多得多):

测试

var now = require("performance-now");

var mapKeyValue = new Map();
var mapStringKeyValue = new Map();
var objectKeyValue = {};
var n = 10000;
var testSamples = 100;

var firstRow = 0;
var firstRowString = firstRow + "";

var middleRow = Math.floor(n / 2);
var middleRowString = middleRow + "";

var lastRow = n - 1;
var lastRowString = lastRow + "";

var nonExist = n * 2;
var nonExistString = nonExist + "";

function makeid() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

for (var i = 0; i < 20; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));

return text;
}

for (var i = 0; i < n; i++) {
var value = makeid();
mapKeyValue.set(i, value);
mapStringKeyValue.set(i + "", value);
objectKeyValue[i + ""] = value;
}

var t0, t1;

var averages = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

for (var j = 0; j < testSamples; j++) {
var k = 0;
t0 = now();
mapKeyValue.get(firstRow);
t1 = now();
averages[k++] += (t1 - t0);

t0 = now();
mapStringKeyValue.get(firstRowString);
t1 = now();
averages[k++] += (t1 - t0);

t0 = now();
objectKeyValue[firstRowString];
t1 = now();
averages[k++] += (t1 - t0);


t0 = now();
mapKeyValue.get(middleRow);
t1 = now();
averages[k++] += (t1 - t0);

t0 = now();
mapStringKeyValue.get(middleRowString);
t1 = now();
averages[k++] += (t1 - t0);

t0 = now();
objectKeyValue[middleRowString];
t1 = now();
averages[k++] += (t1 - t0);


t0 = now();
mapKeyValue.get(lastRow);
t1 = now();
averages[k++] += (t1 - t0);


t0 = now();
mapStringKeyValue.get(lastRowString);
t1 = now();
averages[k++] += (t1 - t0);

t0 = now();
objectKeyValue[lastRowString];
t1 = now();
averages[k++] += (t1 - t0);


t0 = now();
mapKeyValue.get(nonExist);
t1 = now();
averages[k++] += (t1 - t0);

t0 = now();
mapStringKeyValue.get(nonExistString);
t1 = now();
averages[k++] += (t1 - t0);

t0 = now();
objectKeyValue[nonExistString];
t1 = now();
averages[k++] += (t1 - t0);
}

console.log("Test samples number " + testSamples);

for (var i = 0; i < averages.length; i++) {
averages[i] /= testSamples;
console.log("Test case " + (i + 1) + " took in average " + (averages[i] * 1000000) + " ns");
}

结果
Test samples number 100
Test case 1 took in average 2050.269999999692 ns
Test case 2 took in average 751.2899999997202 ns
Test case 3 took in average 567.3000000004081 ns
Test case 4 took in average 727.2699999999688 ns
Test case 5 took in average 4760.029999999489 ns
Test case 6 took in average 1939.3400000004135 ns
Test case 7 took in average 673.549999999885 ns
Test case 8 took in average 689.3600000002564 ns
Test case 9 took in average 541.3700000001143 ns
Test case 10 took in average 1146.0599999999843 ns
Test case 11 took in average 3096.7699999998285 ns
Test case 12 took in average 644.7400000000058 ns

如果您对如何改进基准并使其更准确有任何想法,请告诉我。谢谢你。

最佳答案

我刚刚有一个类似的问题并写了一个测试用例,第一个答案与你的相似,但是我们都没有认为现代 JS 引擎非常有能力消除与函数结果无关的代码。

这意味着您的测试用例向您显示了误导性的结果,因为 JS 引擎能够完全删除您的测试用例,因此您测量了引擎运行空循环的速度。

我编写了一个新的测试用例,确保浏览器没有机会消除代码,结果表明映射几乎是关联对象的两倍:
https://jsperf.com/map-vs-object-vs-frozen

performance test results

请注意,此测试不包括实际初始化 Map 对象的成本。因此,实际上,将本地对象用于小段代码很可能会更快,而实际 map 只有在您在全局上下文中存储大量数据的情况下才会更快。

有趣的是,浏览器意识到对象上没有写操作,因此忽略了它本来必须做的所有更新检查。因此,卡住的性能实际上更慢,而人们预计它会更快。

关于Javascript 对象与 map 性能(Chrome、V8、Node JS),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32886522/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com