Arrays NodeJS array.indexof比set.has快几个数量级,set.has比array.indexof快几个数量级!==-1.
我知道时间复杂度对大输入有影响,但对于任何输入数组,indexof都更快。 例如,对于n=20.000,阵列需要0.008ms,而set需要0.4ms 我使用以下代码测试了array vs set:Arrays NodeJS array.indexof比set.has快几个数量级,set.has比array.indexof快几个数量级!==-1.,arrays,node.js,set,Arrays,Node.js,Set,我知道时间复杂度对大输入有影响,但对于任何输入数组,indexof都更快。 例如,对于n=20.000,阵列需要0.008ms,而set需要0.4ms 我使用以下代码测试了array vs set: const NS_PER_SEC = 1e9; const MS_PER_NS = 1e-6 function runTest(test) { let time = process.hrtime(); test(); let diff = process.hrtime(ti
const NS_PER_SEC = 1e9;
const MS_PER_NS = 1e-6
function runTest(test) {
let time = process.hrtime();
test();
let diff = process.hrtime(time);
return (diff[0] * NS_PER_SEC + diff[1]) * MS_PER_NS
}
function makeRandomString() {
let length = Math.round(Math.random() * 4 + 2);
let result = '';
let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789- ';
let charactersLength = characters.length;
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;//Math.floor(Math.random()); //result;
}
function main() {
let testCases = [10, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 40000, 100000, 10000000];
let times = 5000;
let words = [];
for (let i = 0; i < times; i++) {
words.push(makeRandomString());
}
for (let tci = 0; tci < testCases.length; tci++) {
let array = [];
const items = testCases[tci];
for (let i = 0; i < items; i++) {
array.push(makeRandomString());
}
console.log('List ' + items);
for (let i = 0; i < 10; i++) {
let res = runTest( () => {
for (let j = 0; j < times; j++) {
let tmp = array.indexOf(words[j]);
}
});
console.log(res);
}
console.log('Set ' + items);
let set = new Set(array);
for (let i = 0; i < 10; i++) {
let res = runTest(() => {
for (let j = 0; j < times; j++) {
let tmp = set.has(words[j]);
}
});
console.log(res);
}
}
}
main();
进入:
我得到了预期的结果-例如,对于n=20.000,数组需要333ms,设置为0.4ms
这怎么可能?当然!==-1
不能将生产线的速度降低几个数量级。我不同意“数量级”的速度比。我认为存在某种V8代码缓存机制触发,这就是为什么您会看到这些结果
当我查看您的代码时,我看到您正在使用相同的值运行相同的测试10次:
for (let i = 0; i < 10; i++) {
let res = runTest(() => {
for (let j = 0; j < times; j++) {
let tmp = array.indexOf(words[j]);
}
});
console.log(res);
}
请注意300000项数组的值。indexOf
为0.851231 ms使用时可能会发生代码缓存==代码>缓存无法进行。我不同意这比缓存慢“数量级”。我认为存在某种V8代码缓存机制触发,这就是为什么您会看到这些结果
当我查看您的代码时,我看到您正在使用相同的值运行相同的测试10次:
for (let i = 0; i < 10; i++) {
let res = runTest(() => {
for (let j = 0; j < times; j++) {
let tmp = array.indexOf(words[j]);
}
});
console.log(res);
}
请注意300000项数组的值。indexOf
为0.851231 ms使用时可能会发生代码缓存==代码>缓存无法进行。您好,谢谢您的回复。测试是正确的(就像你的一样),我只是做了几次测试来查看差异。我真的怀疑代码缓存是否发生了。我在网上的任何地方都找不到答案,但我怀疑array.indexOf行在某种程度上被V8引擎优化了,因为它的结果从未被使用过。这可能是原因吗?这种优化是可能的,但我们再次谈论的是可能性,而不是这种行为的实际原因。如果应该给出确切的答案,我们需要去调查核心团队的成员或其他人来回答这个问题。无论如何,我建议您使用Set.has
,因为在所有的测试中,它看起来都非常稳定,并且给出了非常好的结果:)嗨,谢谢您的回复。测试是正确的(就像你的一样),我只是做了几次测试来查看差异。我真的怀疑代码缓存是否发生了。我在网上的任何地方都找不到答案,但我怀疑array.indexOf行在某种程度上被V8引擎优化了,因为它的结果从未被使用过。这可能是原因吗?这种优化是可能的,但我们再次谈论的是可能性,而不是这种行为的实际原因。如果应该给出确切的答案,我们需要去调查核心团队的成员或其他人来回答这个问题。无论如何,我建议您使用Set.has
,因为在所有的测试中,它看起来都非常稳定,并且给出了非常好的结果:)
for (let i = 0; i < 10; i++) {
let res = runTest(() => {
for (let j = 0; j < times; j++) {
let tmp = array.indexOf(words[j]);
}
});
console.log(res);
}
const NS_PER_SEC = 1e9;
const MS_PER_NS = 1e-6
function runTest(test) {
let time = process.hrtime();
test();
let diff = process.hrtime(time);
return (diff[0] * NS_PER_SEC + diff[1]) * MS_PER_NS
}
function makeRandomString() {
let length = Math.round(Math.random() * 4 + 2);
let result = '';
let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789- ';
let charactersLength = characters.length;
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
function main() {
let testCases = [100000, 200000, 300000, 400000];
let times = 5000;
let testResults = {};
for (let tci = 0; tci < testCases.length; tci++) {
let array = [];
let words = [];
const items = testCases[tci];
for (let i = 0; i < times; i++) {
words.push(makeRandomString());
}
for (let i = 0; i < items; i++) {
array.push(makeRandomString());
}
let set = new Set(array);
let msSetTest = runTest(() => {
for (let j = 0; j < times; j++) {
let tmp = set.has(words[j]);
}
});
let msArrayIndexOfTest = runTest(() => {
for (let j = 0; j < times; j++) {
let tmp = array.indexOf(words[j]);
}
});
let msArrayIndexOfEqTest = runTest(() => {
for (let j = 0; j < times; j++) {
let tmp = array.indexOf(words[j]) !== -1;
}
});
testResults[`${items} items`] = { 'Set.has (ms)': msSetTest, 'Array.indexOf (ms)': msArrayIndexOfTest, 'Array.indexOf !== -1 (ms)': msArrayIndexOfEqTest };
}
console.table(testResults);
}
main();
┌──────────────┬────────────────────┬────────────────────┬───────────────────────────┐
│ (index) │ Set.has (ms) │ Array.indexOf (ms) │ Array.indexOf !== -1 (ms) │
├──────────────┼────────────────────┼────────────────────┼───────────────────────────┤
│ 100000 items │ 1.0594569999999999 │ 1335.504929 │ 1341.52334 │
│ 200000 items │ 2.264941 │ 2004.631142 │ 2931.9868469999997 │
│ 300000 items │ 2.2363969999999997 │ 0.851231 │ 4597.312417 │
│ 400000 items │ 1.05495 │ 5333.842428999999 │ 5308.093365 │
└──────────────┴────────────────────┴────────────────────┴───────────────────────────┘