为什么里面加入一个​​if语句这种方法慢下来得这么厉害? [英] Why does adding an If-statement inside a this method slow it down so drastically?

查看:190
本文介绍了为什么里面加入一个​​if语句这种方法慢下来得这么厉害?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在<一碰到这个href="http://stackoverflow.com/questions/12233594/faster-way-to-apply-alpha-to-a-jpeg-in-an-android-app">answering另一个问题。我试图诊断其中code变化对速度的影响更大。我用了一个布尔标志在for循环中使用辅助方法之间切换,以构建一个颜色

I came across this in answering another question. 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 Color.

有趣的现象是,当我决定哪一个是速度更快,并删除了,如果的code的速度放大10倍。以140ms的面前,只是13毫秒之后。我只应删除一个计算出的约7的循环。为什么在这样的速度急剧增加?

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?

<打击> 慢速code:(运行在141毫秒时 helperMethods 是假的) *请参阅编辑2

Slow code: (runs in 141 milliseconds when helperMethods is false) *See edit 2

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);
}

快code:(在13毫秒运行)

Fast Code: (Runs in 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);
}

编辑:看来这个问题是不符合事实,如果是内循环。如果我提升如果的循环之外。在code稍快一些,但仍运行在较慢的速度与131ms:

It seems the issue is not with the fact that the if is inside the loop. If I elevate the if outside of the loop. The code runs slightly faster but still at the slow speeds with 131ms:

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语句。

EDIT 2: 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 getPixel instead of getPixels. I had this flag set wrong for all of my calls that have the helperMethod parameter. When I made new calls to the version without helperMethod I did it correct. The performance boost is because of getPixels not the if statement.

实际慢code:

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次

推荐答案

这可能是你分析code,即混淆你。尝试隔离,你要分析,只是衡量的部分,避免像在你的情况下,创建位图GCable操作code中的一部分。

It is probably your profiling code, that confusing you. Try to isolate the part of the code that you want to profile and just measure that part, avoid GCable operations like creating Bitmaps in your cases.

如果我打电话给你测试code与

If I call your test code with

testing.loadDrawable(this, false, true, false)

运行缓慢。但是,如果我把它与

it runs slow. But if I call it with

testing.loadDrawable(this, true, true, false)

这是一个类似的(更坏)的数量。所以useGetPixels使所有的差异。我的猜测得到位图数据到本地缓冲区设置的结果后。

That's a similar (still worse) number. So useGetPixels makes all the difference. Which I guess gets the Bitmap data into a local buffer and set the results later.

这篇关于为什么里面加入一个​​if语句这种方法慢下来得这么厉害?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆