javascript 配列の値を1つ追加する処理で「length」と「push」とのパフォーマンスを計測する

javascript 配列の値を1つ追加する処理で「length」と「push」とのパフォーマンスを計測する

javascriptで、「length」と「push」で同じ配列の値を1つ追加する処理を行った時のパフォーマンスを計測するサンプルコードを記述してます。「push」の方が少しだけ速そうです。

環境

  • OS windows11 pro 64bit
  • Apache 2.4.43
  • ブラウザ chrome 108.0.5359.125

パフォーマンス計測

「performance.now」を使用して、「length」と「push」を使用して、
配列の値を1つ追加する処理を100万回実行し、パフォーマンスを計測するサンプルコードとなります。

<script>

    // 実行回数
    const times = 1_000_000;

    // 空白を埋めるだけの関数
    function spacePadding(val, n = 8) {
        for (; val.length < n; val += ' ');
        return val;
    }

    // 計測結果を表示
    const benchmark = (name, start, end) => {
        let report = (end - start).toPrecision(3);
        // 表示を見やすくするため関数名に空白を埋める
        name = spacePadding(name)
        console.log(`実行回数:${times}回 関数名:${name} 実行時間:${report}(ms)`);
    }

    let arr = [];    

    // 計測
    start = performance.now();

    for (let i = 0; i < times; ++i) {
        arr = [1, 2, 3]
        arr[arr.length] = 4;
    }

    end = performance.now();

    benchmark('length', start, end);

    // 計測
    start = performance.now();

    for (let i = 0; i < times; ++i) {
        arr = [1, 2, 3]
        arr.push(4)
    }

    end = performance.now();

    benchmark('push', start, end);

</script>

実行結果(chrome 108.0.5359.125)

<1回目>
実行回数:1000000回 関数名:length   実行時間:85.0(ms)
実行回数:1000000回 関数名:push     実行時間:58.0(ms)

<2回目>
実行回数:1000000回 関数名:length   実行時間:58.4(ms)
実行回数:1000000回 関数名:push     実行時間:32.1(ms)

<3回目>
実行回数:1000000回 関数名:length   実行時間:56.2(ms)
実行回数:1000000回 関数名:push     実行時間:37.4(ms)

「push」の方が少しだけ速いという結果になりました。

firefox107でも、少し「push」の方が速そうです。

<1回目>
実行回数:1000000回 関数名:length   実行時間:21.0(ms)
実行回数:1000000回 関数名:push     実行時間:22.0(ms)

<2回目>
実行回数:1000000回 関数名:length   実行時間:26.0(ms)
実行回数:1000000回 関数名:push     実行時間:21.0(ms)

​<3回目>
実行回数:1000000回 関数名:length   実行時間:23.0(ms)
実行回数:1000000回 関数名:push     実行時間:19.0(ms)

safari15.5でも、少し「push」の方が速そうです。

<1回目>
実行回数:1000000回 関数名:length   実行時間:131(ms)
実行回数:1000000回 関数名:push     実行時間:115(ms)

<2回目>
実行回数:1000000回 関数名:length   実行時間:114(ms)
実行回数:1000000回 関数名:push     実行時間:90(ms)

​<3回目>
実行回数:1000000回 関数名:length   実行時間:122(ms)
実行回数:1000000回 関数名:push     実行時間:115(ms)

配列の要素を増やす

配列の要素を1000個にして、そこに要素を追加しても「push」の方が速そうです。

<script>

    // 実行回数
    const times = 10_000;

    // 空白を埋めるだけの関数
    function spacePadding(val, n = 8) {
        for (; val.length < n; val += ' ');
        return val;
    }

    // 計測結果を表示
    const benchmark = (name, start, end) => {
        let report = (end - start).toPrecision(3);
        // 表示を見やすくするため関数名に空白を埋める
        name = spacePadding(name)
        console.log(`実行回数:${times}回 関数名:${name} 実行時間:${report}(ms)`);
    }

    let arr = [];    

    // 計測
    start = performance.now();

    for (let i = 0; i < times; ++i) {
        arr = [...Array(1000)].map( (x, i) => i + 1 )
        arr[arr.length] = 1001;
    }

    end = performance.now();

    benchmark('length', start, end);

    // 計測
    start = performance.now();

    for (let i = 0; i < times; ++i) {
        arr = [...Array(1000)].map( (x, i) => i + 1 )
        arr.push(1001)
    }

    end = performance.now();

    benchmark('push', start, end);

</script>

実行結果(chrome 108.0.5359.125)

<1回目>
実行回数:1000000回 関数名:length   実行時間:527(ms)
実行回数:1000000回 関数名:push     実行時間:515(ms)

<2回目>
実行回数:1000000回 関数名:length   実行時間:544(ms)
実行回数:1000000回 関数名:push     実行時間:528(ms)

<3回目>
実行回数:1000000回 関数名:length   実行時間:542(ms)
実行回数:1000000回 関数名:push     実行時間:519(ms)