2

JavaScript パフォーマンス コンテスト用のテスト プラットフォームを構築しています。タスクの 1 つは、カンバス アニメーションの処理を担当する JavaScript コードを最適化することを競技者に課します。ソリューションが送信された後、サーバーはPhantomJSを使用してソリューションを実行し、アニメーションの 20 秒後に平均 FPS 数を読み取ります。問題は、最適化されたコードと最適化されていないコードの両方で 3 ~ 4 FPS が得られることです。これにより、コードが改善されたかどうかを判断できなくなります。

いくつかの事実:

  • phanotmjs がアニメーションを正しくレンダリングしていることは 100% 確信しています (いくつかのスクリーンショットを作成しました)。
  • ブラウザーでは、最適化されていないコードは 13 FPS で実行され、最適化されたコードは 58 FPS で実行されます
  • phantomjsはサポートしていないため、ポリフィルrequestAnimationFrameを使用する必要がありました
  • 以下のコードを使用して、FPS の数をテストしています。

frameCounter.js

 var frameCounter = (function() {
    var frames = 0;
    var startTime = new Date();

    function bump() {
        frames++;
        window.requestAnimationFrame(bump);
    }

    bump();

    return {
        getFPS: function() {
            var time = (new Date() - startTime) / 1000;

            return (frames/time).toPrecision(4);
        }
    }
 })();

私の質問は、キャンバスアニメーションのパフォーマンスをプログラムで測定するにはどうすればよいですか?

4

3 に答える 3

2

数か月前に、特に FPS と消費量を測定するための小さなスクリプトを書きましたrequestAnimationFrame

100%役立つかどうかはわかりませんが、良い指針を与えることができます.

メータースナップ

使い方はとても簡単です:

  • メーターとして使用する div 要素を指定するループの前のコードのどこかでメーターを初期化します。
  • requestAnimationFrame で指定された引数を必ず取得してください。これにより、費やされた時間がわかります (そうでない場合は、日付/時刻メソッドの使用にフォールバックします)。
  • この引数を使用して、そのメソッドへの単純な呼び出しを行います。

緑色は、最適な FPS (ほとんどの場合 60) 内で実行していることを示します。黄色は、ループが約 16.7 ミリ秒を超えて消費し、レートが約半分になっていることを意味します。オレンジ色は、予算の 2 倍以上を使用していることを意味します。

メーターは加重 FPS を使用して、より正確な測定値を提供します。

var meter = new animMeter('divElementId');

function animate(timeArg) {

    /// funky stuff here

    meter.update(timeArg);

    requestAnimationFrame(animate);
}

この動作のデモは、ここにあります

メーター自体のコードは、最小化されたほぼ下部にあります。自由にコピーして貼り付けてください。MITライセンスが付属しています。

このようなメーターを使用する場合はいつものように、グラフィックを更新するために数ミリ秒を消費し、小さなエラー マージンを導入します。

注意すべきもう 1 つの点は、rAF は常に 60 FPS を達成しようとして実行されるため、メーターがこれよりも高いフレーム レートを測定することは決してないということです。

より高いフレーム レートを測定する必要がある場合は、引数なしで update メソッドを呼び出し、setTimeoutrAF の代わりに使用することができます。パフォーマンスを測定するために日付/時刻が使用されます。わずかに不正確ですが、より高い FPS 値を取得できます (つまり、任意のフレームであるとにかく、モニターは同期されているよりも多くのフレームを表示できません..通常は60 fpsです)。

于 2013-10-01T22:07:21.100 に答える
2

phantomjs はどのアニメーションでも 3 ~ 4 FPS 以上を生成できないように思われるため、このタスクには「実際の」ブラウザーを使用することになりました。Chrome のリモート デバッグ プロトコルのおかげで自動化できました。

テストする新しいコードがあるたびに、次の手順を実行する node.js アプリを作成しました。

  • Chrome ブラウザーのタブに接続されている (ブラウザーは--remote-debugging-port=9222フラグ付きで実行されている必要があります)
  • タブをテスト ページに移動
  • 300 フレームのアニメーションをできるだけ速くレンダリングしようとしたタブ内の評価済みコード
  • 実行時間を返しました

これが私のコードのスニペットです:

//connect to a tab (you can find <tab-debug-id> on http://localhost:9222/json page)
var ws = new WebSocket("ws://localhost:9222/devtools/page/<tab-debug-id>");

ws.onerror = function() {
  //handle error
};

ws.onopen = function()
{
    //when connection is opened hard reload the page before we start
    ws.send(JSON.stringify({
        id: 1,
        method: "Page.reload",
        params: {
            ignoreCache: true
        }
    }));
};

ws.onmessage = function (evt)
{
    var data = JSON.parse(evt.data);

    if(data.id === 1) {
        //reload was successful - inject the test script
        setTimeout(function(){
           ws.send(JSON.stringify({
              id: 2,
              method: "Runtime.evaluate",
              params: {
                expression: '(' + injectedCode.toString() + '());'
              }
           }));
        }, 1000);
    } else if(data.id === 2) {
        //animation has finished - extract the result
        var result = data.result.result.value;
    }
};
于 2013-10-18T07:59:20.360 に答える
0

Date.now() を使用して、オブジェクトの作成に費やされる時間を削減できます。少なくとも少し精度が向上するはずです

于 2013-10-01T19:48:48.210 に答える