2012-04-12 12 views
2

アンドロイドデバイス用のビットマップ操作アルゴを書き込もうとしているときに、問題が発生しました。for-loopがAndroid搭載端末で非常に遅い

私は1680x128ピクセルのビットマップを持っており、その上にフィルタを適用する必要があります。しかし、この非常にシンプルなコードは、実際にAndroidデバイス(1Ghzプロセッサ搭載のxperia ray)で動作するのに15-20秒ほどかかりました。

私はボトルネックを見つけようとしましたが、できるだけ多くのコード行を減らし、実行する時間はほぼ同じでした。

for (int j = 0; j < 128; j++) { 
    for (int i = 0; i < 1680; i++) { 
     Double test = Math.random(); 
    } 
} 

このようなデバイスでは、単純なfor-loopで操作に時間がかかるのは正常ですか?

私はモバイルデバイスでプログラミングするのがとても新しいので、この質問がばかげている場合は申し訳ありません。

更新:いくつかの簡単な操作で、より速くなりました。

しかし、戻って私の主な問題に:

public static void filterImage(Bitmap img, FilterStrategy filter) { 
    img.prepareToDraw(); 
    int height = img.getHeight(); 
    int width = img.getWidth(); 
      RGB rgb; 
    for (int j = 0; j < height; j++) { 
     for (int i = 0; i < width; i++) { 
      rgb = new RGB(img.getPixel(i, j)); 
      if (filter.isBlack(rgb)) { 
       img.setPixel(i, j, 0); 
      } else 
       img.setPixel(i, j, 0xffffffff); 
     } 
    } 
    return; 
} 

上記のコードは、私が本当に速く、デバイス上で実行するために必要なものです。 (ほぼ即時) 最適化の可能性はありますか?

RGBは赤、緑、青の値を計算する唯一のクラスであり、3つの色のすべてが100未満または指定された値未満の場合、フィルターは単にtrueを返します。 すでにimg.getPixel(i、j)またはsetPixelの周りのループは20秒以上かかります。これはそのような高価な操作ですか?

答えて

1

まず第一に、スティーブンCは良い議論をしています。一組のRGBオブジェクトを作成しないようにしてください。すべての

第二に、私はいくつかの簡単なテストを行い、約10%まで実行時にカットするために管理しgetPixels

に1回の呼び出しでgetPixelにご比較的高価な呼び出しを置き換えることによって、巨大な改善を行うことができます。やってみて。これは私が使用したコードでした:

int[] pixels = new int[height * width]; 
img.getPixels(pixels, 0, width, 0, 0, width, height); 

for(int pixel:pixels) { 
    // check the pixel 
} 
+0

ええ、私は一瞬で試してみます。これまでにありがとうございました。 – Woyzeck

+0

これといくつかの他の変更は、algoをスピードアップしました。このクイックアドバイスありがとう:) – Woyzeck

3
ダブルタイプのあまりに多くのオブジェクトが作成されているので、それが...かもしれので、それはヒープサイズを増やすと、デバイスが凍結を開始

..

方法は周り

double[] arr = new double[128] 
for (int j = 0; j < 128; j++) { 
    for (int i = 0; i < 1680; i++) { 
     arr[i] = Math.random(); 
    } 
} 
+0

ダブルテスト; (int i = 0; i <100; i ++)の場合、 for(int j = 0; j <500; j ++) の場合 test = Math.random(); //これは高速ではありません... – Woyzeck

+0

@Woyzeck ..どういう意味ですか..? – ngesh

+0

申し訳ありませんが、コメントは現在編集されています – Woyzeck

1

がで免責事項ありあり以下のドキュメントでは、パフォーマンスに影響を与える可能性のある乱数について説明します。静的バージョンを使用するのではなく、インスタンスを作成してみましょう。太字のパフォーマンス免責事項を強調表示しています。

n> = 0.0 & &n <1。このメソッドは、Randomの単一のインスタンスを再利用します。このメソッドは、ランダムへのアクセスが同期されるためスレッドセーフですが、これはスケーラビリティに悪影響を与えます。 アプリケーションは、スレッドごとにランダムを割り当てることで、パフォーマンス上の利点を見出すことができます。次に、以下のようにそれを使用

private static Random random = new Random(); 

double r = random.nextDouble(); 

もフロート(random.nextFloatを使用することを検討して

が同期アクセスを避けるために、あなたのクラスの静的フィールドとして、独自のランダムを作成してみてください()を使用します。

0

RGBは、赤、緑、青の値を計算するクラスに過ぎず、3つの色のすべてが指定値以下であればtrueを返します。

一つの問題は、あなたは、単に単一pizelが黒であるかどうかをテストするために、RGBクラスのheight * widthインスタンスを作成しているということです。そのメソッドを静的メソッド呼び出しで置き換えます。静的メソッド呼び出しでは、テストするピクセルを引数として取ります。より一般的に


コードのいくつかの作品が遅い理由がわからない場合は、... それをプロファイル。この場合、プロファイラは、RGBコンストラクタにかなりの時間を費やしていることを伝えます。また、メモリプロファイラは、多数のRGBオブジェクトが作成され、ガベージコレクトされていることを伝えます。

+0

良い点ですが、これらすべてのラインをコメントアウトしてすべてのピクセルを繰り返し黒に設定しても、コードは20秒間続きます。どうして? – Woyzeck

+0

提案したようにプロファイルしましたか? –

+0

私は現時点でやっています。 setPixelによりcheckPixelAccess(45%)と他のメソッドが毎回実行されます。 nativeSetPixel呼び出し自体は、各setPixel呼び出しのCPU時間がわずか7%です。 @sandisコードを試してみましょう。これは、これらの無意味な呼び出しを避けるために役立ちます。 – Woyzeck

関連する問題