javascript オブジェクトのプロパティ追加処理で「.」と「[]」のパフォーマンスを計測する

javascript オブジェクトのプロパティ追加処理で「.」と「[]」のパフォーマンスを計測する

javascriptで、「.」と「[]」で同じオブジェクトのプロパティ追加処理を行った時のパフォーマンスを計測するサンプルコードを記述してます。結果は、firefoxだけわずかに「[]」を使用したほうが速やそうです。chromeの場合はほぼ同じでした。

環境

  • OS windows11 pro 64bit
  • ブラウザ chrome 109.0.5414.75

パフォーマンス計測

「performance.now」を使用して、「.」と「[]」を使用して、
オブジェクトにプロパティを追加する処理を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 obj = {}

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

    for (let i = 0; i < times; ++i) {
        obj = { a: 1, b: 2 }
        obj.c = 3
    }

    end = performance.now();

    benchmark('.c', start, end);

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

    for (let i = 0; i < times; ++i) {        
        obj = { a: 1, b: 2 }
        obj['c'] = 3
    }

    end = performance.now();

    benchmark('[c]', start, end);

</script>

実行結果(chrome 109.0.5414.75)

<1回目>
実行回数:1000000回 関数名:.c       実行時間:15.3(ms)
実行回数:1000000回 関数名:[c]      実行時間:13.9(ms)

<2回目>
実行回数:1000000回 関数名:.c       実行時間:21.6(ms)
実行回数:1000000回 関数名:[c]      実行時間:11.7(ms)

<3回目>
実行回数:1000000回 関数名:.c       実行時間:15.8(ms)
実行回数:1000000回 関数名:[c]      実行時間:16.1(ms)

ほぼ同じという結果になりました。

firefox101のは「[c]」が少し速そうです。

<1回目>
実行回数:1000000回 関数名:.c       実行時間:32.0(ms)
実行回数:1000000回 関数名:[c]      実行時間:29.0(ms)
​
<2回目>
実行回数:1000000回 関数名:.c       実行時間:35.0(ms)
実行回数:1000000回 関数名:[c]      実行時間:26.0(ms)

​<3回目>
実行回数:1000000回 関数名:.c       実行時間:30.0(ms)
実行回数:1000000回 関数名:[c]      実行時間:25.0(ms)

safari15.5も同様となります。

<1回目>
実行回数:1000000回 関数名:.c       実行時間:40.0(ms)
実行回数:1000000回 関数名:[c]      実行時間:31.0(ms)
​
<2回目>
実行回数:1000000回 関数名:.c       実行時間:45.0(ms)
実行回数:1000000回 関数名:[c]      実行時間:38.0(ms)

​<3回目>
実行回数:1000000回 関数名:.c       実行時間:39.0(ms)
実行回数:1000000回 関数名:[c]      実行時間:35.0(ms)

Object.assignとスプレッド構文

Object.assignとスプレッド構文を使用してもプロパティは追加できますが、パフォーマンスは悪くなります。

<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 obj = {}

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

    for (let i = 0; i < times; ++i) {
        obj = { a: 1, b: 2 }
        obj.c = 3
    }

    end = performance.now();

    benchmark('.c', start, end);

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

    for (let i = 0; i < times; ++i) {
        obj = { a: 1, b: 2 }
        obj['c'] = 3
    }

    end = performance.now();

    benchmark('[c]', start, end);

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

    for (let i = 0; i < times; ++i) {
        obj = { a: 1, b: 2 }
        Object.assign(obj, { c: 3 });
    }

    end = performance.now();

    benchmark('Object.assign', start, end);


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

    for (let i = 0; i < times; ++i) {
        obj = { a: 1, b: 2 }
        obj = { ...obj, ...{ c: 3 } };
    }

    end = performance.now();

    benchmark('...', start, end);

</script>

実行結果

<chrome 103>
実行回数:1000000回 関数名:.c       実行時間:59.4(ms)
実行回数:1000000回 関数名:[c]      実行時間:45.5(ms)
実行回数:1000000回 関数名:Object.assign 実行時間:63.7(ms)
実行回数:1000000回 関数名:...      実行時間:475(ms)

<firfox 102>
実行回数:1000000回 関数名:.c       実行時間:39.0(ms)
実行回数:1000000回 関数名:[c]      実行時間:30.0(ms)
実行回数:1000000回 関数名:Object.assign 実行時間:88.0(ms)
実行回数:1000000回 関数名:...      実行時間:208(ms)

<safari 15.5>
実行回数:1000000回 関数名:.c       実行時間:38.0(ms)
実行回数:1000000回 関数名:[c]      実行時間:34.0(ms)
実行回数:1000000回 関数名:Object.assign 実行時間:110(ms)
実行回数:1000000回 関数名:...      実行時間:243(ms)