文字列全体で1回drawTextを呼び出すことと、文字列内の各文字(または単語)に対してdrawTextを呼び出すことには大きな違いがありますか?
2 に答える
楽しみのために、私はこれについてテストをまとめました。主にJavaからネイティブコードへのコンテキストスイッチの数が減ったため、文字列全体の描画が速くなると思いました。結果は興味深いものでした。
テストは次のとおりです。次のように、Viewを拡張し、onDrawを実装する単純なカスタムビューを作成しました。
String text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String t[] = {"A","B","C","D","E","F","G","H","I","J",
"K","L","M","N","O","P","Q","R","S","T",
"U","V","W","X","Y","Z"};
long fulltime=0;
double fullavetime=0;
long fullcount=0;
long chartime=0;
double charavetime=0;
long charcount=0;
@Override
protected void onDraw(Canvas canvas) {
float width = (float) getWidth();
float inc=width/26;
float y1 = (float) getHeight() / 3;
float y2 = y1*2;;
float x=0;
// do this test loop 1000 times to get time data
if (fullcount < 1000) {
// test by char using a simple 26 char string
// I tried to eliminate as much overhead as possible
// so this just pulls strings from an array and draws them
long start=System.currentTimeMillis();
for (int i=0;i<26;i++) {
canvas.drawText(t[i], x, y1, textPaint);
x+=inc;
}
long end=System.currentTimeMillis();
long elapse=end-start;
chartime+=elapse;
charcount++;
charavetime=(double)chartime/charcount;
// draw the entire 26 char string at once
x=0f;
start=System.currentTimeMillis();
canvas.drawText(text, x, y2, textPaint);
end=System.currentTimeMillis();
elapse=end-start;
fulltime+=elapse;
fullcount++;
fullavetime=(double)fulltime/fullcount;
} else {
// after the 1000 test draws, just paint the results on screen
canvas.drawText("bychar "+charavetime, 0, y1, textPaint);
canvas.drawText(" full "+fullavetime, 0, y2, textPaint);
}
// keep painting over and over
invalidate();
}
手元にある3台の電話でこれを実行しました。結果は次のとおりです。
HTC EVO 4G (2.2)
bychar 1.055 1.142 1.184
full .398 .354 .432
Motorola Droid (2.1 up 1)
bychar .951 1.108 1.071
full .138 .146 .134
Nexus One (2.3.3)
bychar .991 1.033 1.045 .938
full .839 .886 .891 .819
また、bycharの結果が10倍のフルストリングの結果でコミカルに歪んだエミュレーターも実行しました。
結果にはいくつかの驚きがあります。明らかに、モトローラドロイドは非常に高速なネイティブテキストペインティングルーチンを備えており、Javaからネイティブサンクまでも同様に低速です。
いつものように、コードを再確認してください。テストを歪めるようなことをした可能性があります。
私の持ち帰りは、可能な限り完全な文字列を描画する必要があるということです。彼らが言うように、あなたのマイレージは変わるかもしれません。
文字列内の各文字で drawtext を呼び出すと、さまざまなデバイスや画面サイズで位置合わせがずれることがあります。
その問題を克服するコードを書くと、その時点でさらに多くの変数を追跡し、外部のクラスやメソッドを呼び出すことになり、キャンバスの描画が遅くなると思います。(キャンバスが描画中に計算を実行したり、外部クラスを呼び出したりする必要がある場合、キャンバスの速度が低下します)
ondraw は canvas の継承メソッドであるため、複数のインスタンスを使用する場合はあまり影響を受けません。その背後にあるすべてのコーディングにより、速度が低下します