強火で進め

このブログではプログラム関連の記事を中心に書いてます。

SafariのCanvasで小数点を含んだ位置に描画すると処理速度が落ちる(高速化するには整数の位置に描画)

HTML5 canvas sprite optimisation | Seb Lee-Delisle
http://sebleedelisle.com/2011/02/html5-canvas-sprite-optimisation/

こちらのブログで「サブピクセルを含んだ描画だと処理速度が落ちる為、整数に補正して位置指定をすべき」という話を見かけました。

この話を簡単に説明するとcanvasでdrawImageで画像を描画する時、Safariなどでは1.5などの中途半端な位置を指定した時にもその位置で描画された様子を表現する為にサブピクセルの描画が行われ、ぼやけた様な描画になります。

以下の画像は左側がdrawImageで整数の位置に描画したもの、右側は同じ画像を小数点を含んだ位置に描画したものになります。右側がサブピクセルの描画が行われぼやけた様な画像になっているのが確認出来るかと思います。

右側の様な描画になった場合は処理速度が落ちる様です。まぁ、描画のクオリティの面でも右側の様な描画は避けたい所では有りますが…

GIFファイルで比較

まずはGIFファイルでテストしてみました。

テストプログラムはこちら。小数点を含んだ位置に描画する最適化無しのサンプルと整数の位置に描画する最適化したサンプルの2つです。

GIFファイルで最適化無しのサンプル
GIFファイルで最適化したサンプル
画面をタップするともう片方のプログラムに切り替わる為、交互に確認出来ます。

テスト結果は以下。テスト環境はiPhone 4、OSは4.3.3。

バックグラウンドで動いてる処理など影響などで測定する人によって結果は異なるかとは思いますが最適化無しと有りを交互に実行しているので2つの実行時の環境にそんなに差異は無いのではと思っています。

プログラムの内容をざっと説明。

主な流れはこうなっています。

開始時刻を保存
  ↓
一定時間おきに描画処理を実行
  ↓
描画処理を100回したら処理を終了
  ↓
開始時の時刻との差分をアラートで表示

ここで「一定時間おきに描画処理を実行」と有りますがこのプログラムでは描画処理が全て終わってから1000/60秒経ってから再度、描画処理を呼ぶ作りになっています。

その為、描画処理の部分が遅ければ遅いほど最後にアラートで表示される数値が大きくなります。

なお、測定開始は画像ファイルのDLが完了したタイミングにしているので通信環境の差異の影響も受けないのはずです。

テストプログラムのフルセットはこちらから落とせます。速度検証の為の使用であればご自由に使って貰って問題無いので面白い検証などが出来てブログを書いたりした時はコメントなど頂けると嬉しいです。

検証結果のデータはこちら。
※数値が大きいほど遅い。

[GIF]無し

スコア
1回目 6763
2回目 6769
3回目 6708
4回目 6780
5回目 6790
平均 6762.0

[GIF]最適化したもの

スコア
1回目 4546
2回目 4806
3回目 5056
4回目 4969
5回目 5305
平均 4936.3999999999996

6762.0/4936.3999999999996 = 1.3698241633579127

1.369、最適化して無いものはおよそ 37% 程度遅くなる様です。

PNGファイルで比較

次にPNGファイルでテストしてみました。

PNGファイルで最適化無しのサンプル
PNGファイルで最適化したサンプル

[PNG]無し

スコア
1回目 7708
2回目 7389
3回目 7437
4回目 7426
5回目 7457
平均 7483.3999999999996

[PNG]最適化したもの

スコア
1回目 6782
2回目 6748
3回目 6709
4回目 6730
5回目 6730
平均 6739.8000000000002

7483.3999999999996/6739.8000000000002 = 1.1103296833733938

1.110、最適化して無いものはおよそ 11% 遅くなる様です。