🦿

【速度調査】getStateComat, setStateCompat, $.state

2022/11/26に公開

こんにちは!かおもです!
ClusterScript(JavaScript)のgetStateComaptとか、実際どれぐらい重いの?という記事です!!

0:調査日

2022.11.25 デスクトップ版 cluster v2.52
で計測しました。

1:結果

項目 比率 秒数 処理(valueKey = "doubleValue")
nop - 0.00 8.23 _ => {}
add value 1.0 0.12 8.36 ticks => ticks + 1
getStateCompat(this) 10.0 1.24 9.47 $.getStateCompat("this", valueKey, "double")
getStateCompat(global) 9.6 1.19 9.42 $.getStateCompat("global", valueKey, "double")
setStateCompat 14.8 1.82 10.06 $.setStateCompat("this", valueKey, ticks)
get $.state[xxx] 3.9 0.48 8.71 $.state[valueKey]
get $.state.xxx 3.3 0.41 8.64 $.state.doubleValue
set $.state[xxx] 6.1 0.75 8.98 $.state[valueKey] = ticks
set $.state.xxx 6.1 0.76 8.99 $.state.doubleValue = ticks

比率は、秒数の差の比で、add valueとの秒数の差を1とした値です。
秒数は、onUpdate毎に処理を行い、その処理が合計500回行われた時の秒数です。
秒数は6回計測し、そのうちの最大値と最小値を除いた4個の平均値です。

2:調査方法の詳細

使用したコード
let valueKey = "doubleValue", loggingKey = "logging";
const subjects = [
    ["nop",                         _ => {}],
    ["nop",                         _ => {}],
    ["nop",                         _ => {}],
    ["getStateCompat(this)",        _ => $.getStateCompat("this", valueKey, "double")],
    ["getStateCompat(global)",      _ => $.getStateCompat("global", valueKey, "double")],
    ["setStateCompat",          ticks => { $.setStateCompat("this", valueKey, ticks); }],
    ["get $.state by bracket",      _ => $.state[valueKey]],
    ["get $.state by dot",          _ => $.state.doubleValue],
    ["set $.state by bracket",  ticks => { $.state[valueKey] = ticks; }],
    ["set $.state by dot",      ticks => { $.state.doubleValue = ticks; }],
    ["add value",               ticks => ticks + 1],
    ["nop",                         _ => {}],
    ["getStateCompat(this)",        _ => $.getStateCompat("this", valueKey, "double")],
    ["getStateCompat(global)",      _ => $.getStateCompat("global", valueKey, "double")],
    ["setStateCompat",          ticks => { $.setStateCompat("this", valueKey, ticks); }],
    ["get $.state by bracket",      _ => $.state[valueKey]],
    ["get $.state by dot",          _ => $.state.doubleValue],
    ["set $.state by bracket",  ticks => { $.state[valueKey] = ticks; }],
    ["set $.state by dot",      ticks => { $.state.doubleValue = ticks; }],
    ["add value",               ticks => ticks + 1],
    ["nop",                         _ => {}],
    ["getStateCompat(this)",        _ => $.getStateCompat("this", valueKey, "double")],
    ["getStateCompat(global)",      _ => $.getStateCompat("global", valueKey, "double")],
    ["setStateCompat",          ticks => { $.setStateCompat("this", valueKey, ticks); }],
    ["get $.state by bracket",      _ => $.state[valueKey]],
    ["get $.state by dot",          _ => $.state.doubleValue],
    ["set $.state by bracket",  ticks => { $.state[valueKey] = ticks; }],
    ["set $.state by dot",      ticks => { $.state.doubleValue = ticks; }],
    ["add value",               ticks => ticks + 1],
];
const doTests = () => {
    if(subjects.length === 0){
        onUpdate = () => {};
        return;
    }

    let i = 0, ticks = 0, value = 0, time = Date.now();
    valueKey = ("XXX" + valueKey).substring(3); //最適化回避のために入れてみたけど意味なかったかも

    if($.getStateCompat("this", loggingKey, "boolean")){
        $.log(`least:${subjects.length}`);
    }
    const subject = subjects.shift();

    onUpdate = dt => {
        ticks += dt;
        if(i++ < 500){
            value = subject[1](ticks);
            return;
        }

        doTests();

        if(!$.getStateCompat("this", loggingKey, "boolean")){
            return;
        }

        const nowDelta = Date.now() - time;
        ticks = ("" + ticks).substring(0, 5);
        $.log(`ticks:${ticks} now:${nowDelta} subject:${subject[0]} value:${value}`);
    };
};

let onUpdate = _ => {};
$.onUpdate(dt => onUpdate(dt));
doTests();
$.log("!!!RESET!!!");

上記のコードを設定したItemを、シーンに50個配置しました。
CPUのクロック数を下げ(1.37GHz)、50-60FPSの状態で計測しています。
doubleValueとloggingの値は、On Create Item Triggerで予め設定しています。

3:感想

setStateCompatが、足し算の約15倍遅いという結果になりました。
ただ、この結果をどう考えるか悩ましいですね…。

  • 単純な足し算が案外遅い?それとも他が早い?(というかこの調査方法でいいのかな?)
  • get/setStateCompatはちょっと気を付けたい。できるだけ$.stateに置き換えたい。
  • 倍精度浮動小数点数で入ってくるシグナルの値も、できれば加工して$.stateに入れたい。加工の負荷によるけども。
  • $.stateのgetは気軽に使えそう。

よいClusterScriptライフを!

Discussion