2015年2月25日水曜日

for文の効率化による動作速度の向上テスト(Android,Java)

色々省略していますが、for文の効率化を実機テストしたメインのコード部分は以下。レイアウトXMLにボタンがあり、押すと計算時間がテキストビューに書き出されるというようになっています。テストした実機はAndroid4.1.2、及びAndroid4.4です。

実行してみると、ローカル変数(n = int_i.length)へ一時キャッシュした方が速くなりました。平均を取っても同様です。やはり、いちいち評価するとわずかながら低速になります(なお、n = int_i.lengthですが、forの外で定義しても構わないといえば構わないのですが、スコープが広くなるので中でやる方がより良いと思います)。

念のためbutton1の中でculc_test1とculc_test2の呼び出し順を入れ替えてみましたが、あまり変わらず、culc_test1の方が速いです。

ただし、int numberの値を5000000に一桁増やした場合、ほぼ常に先に呼びだした方が速くなりました。これは、GCが原因です(そりゃそうだ)。

スピード差は、culc_test1がculc_test2に比べ20%前後高速でした。

ただ、これだけ呼び出しまくっても、実際の実行速度の違いは、

int number = 500000 で1~数ミリ秒程度。

int number = 5000000 で数ミリ秒~10数ミリ秒程度(GCの影響を排除した場合)でした。

※この結果は、当然ながらCPUの種類で大きな差があります。

大きめのプログラムで、効率を気にしなければならないような場合はキャッシュした方が良さそうですが、そうでない場合はコード量がわずかに増えるので、どっちが良いとも言い切れません。

高速化という意味では、Androidの場合、どちらかというとレイアウトXMLの書き方のほうが問題ですね。これは複雑になってくると数百ミリ秒以上の差が出ます。



//フィールド
private static final int number = 500000;
int[] int_i = new int[number];


// ボタン1を押した時に呼び出される関数
public void button1(View v) {
// テキストビューをルックアップして値をセット
TextView txtview = (TextView) findViewById(R.id.txt_test);
String str_setText = culc_test1()+"\n"+ culc_test2();
txtview.setText(str_setText);
}

private String culc_test1(){
int_i = new int[number];
String str1 = "";
long l1 = SystemClock.elapsedRealtime();
for(int i = 0,n = int_i.length; i < n; i++){
int_i[i] = i;
}
long l2 = SystemClock.elapsedRealtime();
str1 += "ローカル変数へグローバル変数から一時キャッシュする場合の計算時間は";
long l3 = l2 -l1;
str1 += l3;
str1 += "ミリ秒です。";
return str1;
}
private String culc_test2(){
int_i = new int[number];
String str1 = "";
long l1 = SystemClock.elapsedRealtime();
for(int i = 0; i < int_i.length; i++){
int_i[i] = i;
}
long l2 = SystemClock.elapsedRealtime();
str1 += "グローバル変数から.lengthで直接取得する場合の計算時間は";
long l3 = l2 -l1;
str1 += l3;
str1 += "ミリ秒です。";
return str1;
}