Arrays NodeJS array.indexof比set.has快几个数量级,set.has比array.indexof快几个数量级!==-1.

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

我知道时间复杂度对大输入有影响,但对于任何输入数组,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(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        │
└──────────────┴────────────────────┴────────────────────┴───────────────────────────┘