私は別の質問に答える際にこれに出くわしました。どのコード変更が速度に大きな影響を与えたかを診断しようとしていました. for ループでブール値フラグを使用して、ヘルパー メソッドを使用してColorを構築する方法を切り替えました。
興味深い動作は、どちらが速いかを判断して、コードの速度が 10 倍に増幅された場合を削除したことです。前に 140 ミリ秒かかり、後はわずか 13 ミリ秒です。ループから約 7 つの計算のうち 1 つだけを削除する必要があります。なぜ、これほどまでに速度が大幅に向上したのでしょうか。
スロー コード:ます) *編集 2 を参照helperMethods
(が false の場合、141 ミリ秒で実行され
public static void applyAlphaGetPixels(Bitmap b, Bitmap bAlpha, boolean helperMethods) {
int w = b.getWidth();
int h = b.getHeight();
int[] colorPixels = new int[w*h];
int[] alphaPixels = new int[w*h];
b.getPixels(colorPixels, 0, w, 0, 0, w, h);
bAlpha.getPixels(alphaPixels, 0, w, 0, 0, w, h);
for(int j = 0; j < colorPixels.length;j++){
if(helperMethods){
colorPixels[j] = Color.argb(Color.alpha(alphaPixels[j]), Color.red(colorPixels[j]), Color.green(colorPixels[j]), Color.blue(colorPixels[j]));
} else colorPixels[j] = alphaPixels[j] | (0x00FFFFFF & colorPixels[j]);
}
b.setPixels(colorPixels, 0, w, 0, 0, w, h);
}
高速コード: (13ms で実行)
public static void applyAlphaGetPixels(Bitmap b, Bitmap bAlpha) {
int w = b.getWidth();
int h = b.getHeight();
int[] colorPixels = new int[w*h];
int[] alphaPixels = new int[w*h];
b.getPixels(colorPixels, 0, w, 0, 0, w, h);
bAlpha.getPixels(alphaPixels, 0, w, 0, 0, w, h);
for(int j = 0; j < colorPixels.length;j++){
colorPixels[j] = alphaPixels[j] | (0x00FFFFFF & colorPixels[j]);
}
b.setPixels(colorPixels, 0, w, 0, 0, w, h);
}
編集: if がループ内にあるという事実には問題がないようです。if
ループの外側を上げると。コードはわずかに高速に実行されますが、それでも 131 ミリ秒と低速です。
public static void applyAlphaGetPixels(Bitmap b, Bitmap bAlpha, boolean helperMethods) {
int w = b.getWidth();
int h = b.getHeight();
int[] colorPixels = new int[w*h];
int[] alphaPixels = new int[w*h];
b.getPixels(colorPixels, 0, w, 0, 0, w, h);
bAlpha.getPixels(alphaPixels, 0, w, 0, 0, w, h);
if (helperMethods) {
for (int j = 0; j < colorPixels.length;j++) {
colorPixels[j] = Color.argb(Color.alpha(alphaPixels[j]),
Color.red(colorPixels[j]),
Color.green(colorPixels[j]),
Color.blue(colorPixels[j]));
}
} else {
for (int j = 0; j < colorPixels.length;j++) {
colorPixels[j] = alphaPixels[j] | (0x00FFFFFF & colorPixels[j]);
}
}
b.setPixels(colorPixels, 0, w, 0, 0, w, h);
}
編集2:私はばかです。ほんとうにばかだ。getPixel
コール スタックの前半で、別のブール値フラグを使用して、このメソッドを使用するか、代わりにを使用する別のメソッドを使用するかを切り替えgetPixels
ました。helperMethod
パラメータを持つすべての呼び出しで、このフラグが間違って設定されていました。バージョンに新しい呼び出しを行ったときhelperMethod
、正しく実行しませんでした。パフォーマンスの向上はgetPixels
、if ステートメントではないためです。
実際のスロー コード:
public static void applyAlphaGetPixel(Bitmap b, Bitmap bAlpha, boolean helperMethods) {
int w = b.getWidth();
int h = b.getHeight();
for(int y=0; y < h; ++y) {
for(int x=0; x < w; ++x) {
int pixel = b.getPixel(x,y);
int finalPixel;
if(helperMethods){
finalPixel = Color.argb(Color.alpha(bAlpha.getPixel(x,y)), Color.red(pixel), Color.green(pixel), Color.blue(pixel));
} else{
finalPixel = bAlpha.getPixel(x,y) | (0x00FFFFFF & pixel);
}
b.setPixel(x,y,finalPixel);
}
}
}
注: すべての速度は 100 回の実行の平均です。