天天看點

性能優化08_記憶體抖動和計算性能優化案例

Android性能優化彙總

案例:加載一個gif檔案(比較占記憶體,模拟正常app的運作顯示),此時出現下面耗時或者很消耗記憶體的情況(我們的代碼寫的不好),(結果)gif檔案的顯示就會受到影響,出現卡頓

1 正常gif的顯示

WebView webView = (WebView) findViewById(R.id.webview);
 webView.getSettings().setUseWideViewPort(true);
   webView.getSettings().setLoadWithOverviewMode(true);
webView.loadUrl("file:///android_asset/shiver_me_timbers.gif");
           

2 計算斐波那契數列導緻卡頓

斐波那契數列:前一個值+目前值 = 下一個值

1) 遞歸造成卡頓

性能優化08_記憶體抖動和計算性能優化案例
public int computeFibonacci(int positionInFibSequence) {
        //0 1 1 2 3 5 8
        if(positionInFibSequence <=2){
            return 1;
        }else{
            return computeFibonacci(positionInFibSequence-1)+computeFibonacci(positionInFibSequence-2);
        }
    }
           
性能優化08_記憶體抖動和計算性能優化案例

2) 使用緩存思想優化後

//優化後的斐波那契數列的非遞歸算法 caching緩存+批處理思想
    public int computeFibonacci(int positionInFibSequence) {
        int pre = 0;
        int current = 1;
        int newValue;
        for (int i = 1; i < positionInFibSequence; i++) {
            newValue = current + pre;
            pre = current;
            current = newValue;
        }
        return current;

    }
           
性能優化08_記憶體抖動和計算性能優化案例

3 排序并列印二位數組

1) 優化前

public void imPrettySureSortingIsFree() {
        int dimension = 300;
        int[][] lotsOfInts = new int[dimension][dimension];

        Random random = new Random();
        for (int i = 0; i < lotsOfInts.length; i++) {
            for (int j = 0; j < lotsOfInts[i].length; j++) {
                lotsOfInts[i][j] = random.nextInt();
            }
        }

        for (int i = 0; i < lotsOfInts.length; i++) {
            String rowAsStr = "";
            //排序
            int[] sorted = getSorted(lotsOfInts[i]);
            //拼接列印
            for (int j = 0; j < lotsOfInts[i].length; j++) {
                rowAsStr += sorted[j];
                if (j < (lotsOfInts[i].length - 1)) {
                    rowAsStr += ",";
                }
            }
            Log.i("ricky", "Row " + i + ": " + rowAsStr);
        }

        //優化以後
        StringBuilder sb = new StringBuilder();
        String rowAsStr = "";
        for (int i = 0; i < lotsOfInts.length; i++) {
            //清除上一行
            sb.delete(0, rowAsStr.length());
            //排序
            int[] sorted = getSorted(lotsOfInts[i]);
            //拼接列印
            for (int j = 0; j < lotsOfInts[i].length; j++) {
                rowAsStr += sorted[j];
                sb.append(sorted[j]);
                if(j < (lotsOfInts[i].length - 1)){
                    rowAsStr += ", ";
                    sb.append(", ");
                }
            }
            rowAsStr = sb.toString();
            Log.i("ricky", "Row " + i + ": " + rowAsStr);
        }
    }

    public int[] getSorted(int[] input) {
        int[] clone = input.clone();
        Arrays.sort(clone);
        return clone;
    }
           
性能優化08_記憶體抖動和計算性能優化案例
2)優化後
public void imPrettySureSortingIsFree() {
        int dimension = 300;
        int[][] lotsOfInts = new int[dimension][dimension];
        Random randomGenerator = new Random();
        for(int i = 0; i < lotsOfInts.length; i++) {
            for (int j = 0; j < lotsOfInts[i].length; j++) {
                lotsOfInts[i][j] = randomGenerator.nextInt();
            }
        }

        // 使用StringBuilder完成輸出,我們隻需要建立一個字元串即可,不需要浪費過多的記憶體
        StringBuilder sb = new StringBuilder();
        String rowAsStr = "";
        for(int i = 0; i < lotsOfInts.length; i++) {
            // 清除上一行
            sb.delete(0, rowAsStr.length());
            //排序
            int[] sorted = getSorted(lotsOfInts[i]);
            //拼接列印
            for (int j = 0; j < lotsOfInts[i].length; j++) {
                sb.append(sorted[j]);
                if(j < (lotsOfInts[i].length - 1)){
                    sb.append(", ");
                }
            }
            rowAsStr = sb.toString();
            Log.i("jason", "Row " + i + ": " + rowAsStr);
        }
    }

    public int[] getSorted(int[] input){
        int[] clone = input.clone();
        Arrays.sort(clone);
        return clone;
    }
           
性能優化08_記憶體抖動和計算性能優化案例

4 BusyUIThread:Display an image.(使用異步處理圖檔RGB色值變換加載)

private class SepiaFilterTask extends AsyncTask<Bitmap, Void, Bitmap> {

        @Override
        protected Bitmap doInBackground(Bitmap... bitmaps) {
            Bitmap loadedBitmap = bitmaps[0];

            int width = loadedBitmap.getWidth();
            int height = loadedBitmap.getHeight();
            Bitmap sepiaBitmap = Bitmap.createBitmap(width, height, loadedBitmap.getConfig());
            // Go through every single pixel in the bitmap, apply a sepia filter to it, and apply it
            // to the new "output" bitmap.
            for (int x = 0; x < width; ++x) {
                for (int y = 0; y < height; ++y) {
                    // get pixel color
                    int pixel = loadedBitmap.getPixel(x, y);
                    int alpha = Color.alpha(pixel);

                    // These are the starting values for this pixel.
                    int inputRed = Color.red(pixel);
                    int inputGreen = Color.green(pixel);
                    int inputBlue = Color.blue(pixel);

                    // These are the sepia-fied values for each pixel.
                    // Note that if the resulting value is over 255, Math.Min brings it back down.
                    // So effectively, min establishes a max value!  Isn't that weird?
                    int outRed = (int) Math.min(  (inputRed * .393) + (inputGreen *.769) + (inputBlue * .189), 255);
                    int outGreen = (int) Math.min(
                            (inputRed * .349) + (inputGreen *.686) + (inputBlue * .168), 255);

                    int outBlue = (int) Math.min(
                            (inputRed * .272) + (inputGreen *.534) + (inputBlue * .131), 255);
                    // apply new pixel color to output bitmap
                    sepiaBitmap.setPixel(x, y, Color.argb(alpha, outRed, outGreen, outBlue));
                }
            }
            return sepiaBitmap;
        }

        @Override
        protected void onPostExecute(Bitmap sepiaBitmap) {
            ImageView imageView = findViewById(R.id.busyui_imageview);
            imageView.setImageBitmap(sepiaBitmap);
        }
    }
           

圖檔處理的一段時間裡,gif正常顯示

性能優化08_記憶體抖動和計算性能優化案例

繼續閱讀