Rust(wasm)の速度性能テスト&JavaScriptでゲームループ改

投稿日:

WebAssembly(Rust)の実行速度を簡単な球の物理計算で性能テストしてみました。あと以前作成したゲームループに問題があったため、処理落ちしても大丈夫なように修正、改良しました。
少し古いPC(Windows10)で30FPSを維持できる個数は、Chromeで5000個、Firefox4500個、Edge2500個でした。低価格スマホ、タブレット(android、Chrome)では1000個。

 

球の物理計算?

物理シミュレーションではなく、それっぽく動くだけの似非物理計算です。重力での落下、壁と床の衝突、球同士の衝突の計算を行っています。球の衝突計算が重すぎるので、事前に不要な計算を省略する最適化を行っています。

球の個数を入力して[start]ボタンを押すと計算がスタートします。その時のFPSと使用メモリが表示されます。とりあえずマウスや画面タッチでカメラが回転できます(実験中)。

実行

□rust-webgl-speedtest

Rustプロジェクトとソースコードです。Windowsコマンドスクリプトでのビルドになります。

“Rust(wasm)の速度性能テスト&JavaScriptでゲームループ改” をダウンロード rust_webgl_speed_test.zip – 19 回のダウンロード – 98 KB

JavaScriptでゲームループ改

以前作成したのもが処理落ちに対応できていなかったので修正、改良しました。できるだけ他のJavaScript処理に制御が移るようにsetTimeoutを利用して処理を分散させました。

ゲームループ.js
let UpdateFPS = 30;
let UpdateStepTime = 1000/UpdateFPS;//ms
let UpdateFrameSkipMax = 8;

let AnimeFrameHdl;//requestAnimationFrame
let TimeoutHdl;//setTimeout
let UpdateLastTime = 0;//前回の更新時間
let FrameSkipCnt = 0;//フレームスキップカウンター

function start()
{
    // ゲームループ開始
    UpdateLastTime = performance.now();
    TimeoutHdl = setTimeout(update_step);
}



function update_step() {
    let now_time = performance.now();
    let time = UpdateLastTime;

    if(time <= now_time) {
        //
        // 更新処理
        //

        time += UpdateStepTime;
        FrameSkipCnt += 1;
        UpdateLastTime = time;

        if(time >= now_time){ //時間更新成功
            FrameSkipCnt = 0;
            //画面更新に合わせて描画実行
            AnimeFrameHdl = requestAnimationFrame(update_render);
            //TimeoutHdl = setTimeout(update_render);//合わせない
            return;
        }
        //まだ遅れている
        
        //間に合わない 時間リセット
        if(FrameSkipCnt >= UpdateFrameSkipMax){
            FrameSkipCnt = 0;
            UpdateLastTime = now_time;
            AnimeFrameHdl = requestAnimationFrame(update_render);
            //TimeoutHdl = setTimeout(update_render);
            return;
        }

        //フレームスキップ継続 
        //連続実行せずに一旦スレッドを解放
        TimeoutHdl = setTimeout(update_step,0);
        return;        
    }

    // ここに来る場合、時間に余裕がある

    let wait_time = time  - now_time;//次回更新までの時間
    if(wait_time < 0)wait_time = 0;
    if(wait_time > UpdateStepTime*1.1){
        UpdateLastTime = now_time;//更新処理が進みすぎ 念のため
        wait_time = 0;
    }
    //次回更新まで待つ
    TimeoutHdl = setTimeout(update_step,wait_time);
}

function update_render() {   
    
    //
    // 描画処理
    //

    TimeoutHdl = setTimeout(update_step,0);
}

コメントを残す

メールアドレスが公開されることはありません。

認証:数字を入力してください(必須) * Time limit is exhausted. Please reload CAPTCHA.