Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy does adding an If-statement inside a this method slow it down so drastically?
    text
    copied!<p>I came across this in <a href="https://stackoverflow.com/questions/12233594/faster-way-to-apply-alpha-to-a-jpeg-in-an-android-app">answering another question</a>. I was trying to diagnose which code change had a greater effect on the speed. I used a boolean flag in a for loop to switch between using helper methods to construct a <a href="http://developer.android.com/reference/android/graphics/Color.html" rel="nofollow noreferrer">Color</a>.</p> <p>The interesting behavior is that when I decided which one was faster and removed the if the speed of the code amplified 10x. Taking 140ms before and just 13ms afterward. I should only be removing one calculation out of about 7 from the loop. Why such a drastic increase in speed?</p> <p><strike><strong>Slow code:</strong> (runs in 141 milliseconds when <code>helperMethods</code> is false)</strike> *See edit 2</p> <pre><code>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 &lt; 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 &amp; colorPixels[j]); } b.setPixels(colorPixels, 0, w, 0, 0, w, h); } </code></pre> <p><strong>Fast Code:</strong> (Runs in 13ms)</p> <pre><code>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 &lt; colorPixels.length;j++){ colorPixels[j] = alphaPixels[j] | (0x00FFFFFF &amp; colorPixels[j]); } b.setPixels(colorPixels, 0, w, 0, 0, w, h); } </code></pre> <p><strong>EDIT:</strong> It seems the issue is not with the fact that the if is inside the loop. If I elevate the <code>if</code> outside of the loop. The code runs slightly faster but still at the slow speeds with 131ms:</p> <pre><code>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 &lt; 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 &lt; colorPixels.length;j++) { colorPixels[j] = alphaPixels[j] | (0x00FFFFFF &amp; colorPixels[j]); } } b.setPixels(colorPixels, 0, w, 0, 0, w, h); } </code></pre> <p><strong>EDIT 2:</strong> I'm dumb. Really really dumb. Earlier in the call stack I used another boolean flag to switch between between using this method and using another method that uses <code>getPixel</code> instead of <code>getPixels</code>. I had this flag set wrong for all of my calls that have the <code>helperMethod</code> parameter. When I made new calls to the version without <code>helperMethod</code> I did it correct. The performance boost is because of <code>getPixels</code> not the if statement.</p> <p><strong>Actual Slow code:</strong> </p> <pre><code>public static void applyAlphaGetPixel(Bitmap b, Bitmap bAlpha, boolean helperMethods) { int w = b.getWidth(); int h = b.getHeight(); for(int y=0; y &lt; h; ++y) { for(int x=0; x &lt; 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 &amp; pixel); } b.setPixel(x,y,finalPixel); } } } </code></pre> <p><em>Note:All speeds are an average of 100 runs.</em></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload