JAVAの最適化(7)
今日は例から最適化をしてみます。
public void foo( int a , int b ){ int i,j,k; for( i = 0 ; i < a ; i++ ){ for( j = 0 ; j < b ; j++ ){ for( k = 0 ; k < 10 ; k++ ){ something( i , j , k ); } } } }
という関数をいろいろと弄ってみましょう。
まず、ループ変数をダウンカウンタにすることが挙げられます。
これは、ダウンカウンタの方が速いからではなくて、バイトコードは、0と比較する専用の命令があるので、0と比較することによって、バイトコードを少なくし、速度を上げることが出来ます。
public void foo( int a , int b ){ int i,j,k; for( i = a - 1 ; i >= 0 ; i-- ){ for( j = b - 1 ; j >= 0 ; j-- ){ for( k = 9 ; k >= 0 ; k-- ){ something( i , j , k ); } } } }
もちろん、ダウンカウンタでも正常に動くかどうかを考える必要があります。
無理なら諦めましょう。
次は、プライム変数のデクリメントを、省略せずに書くことにします。
この中でプライム変数になっているのは、a,b,iなので、i--をi=i-1に変更します。
どうやら、プライム変数に割り当てられた変数は、インクリメント、デクリメントの命令、iincを使うより、普通に演算した方が速いらしいです。
public void foo( int a , int b ){ int i,j,k; for( i = a - 1 ; i >= 0 ; i=i-1 ){ for( j = b - 1 ; j >= 0 ; j-- ){ for( k = 9 ; k >= 0 ; k-- ){ something( i , j , k ); } } } }
いや、むしろ、使用頻度が一番高いkをプライム変数に割り当てて、k=k-1とするべきかもしれません。
public void foo( int a , int b ){ int k,j,i; for( i = a - 1 ; i >= 0 ; i-- ){ for( j = b - 1 ; j >= 0 ; j-- ){ for( k = 9 ; k >= 0 ; k=k-1 ){ something( i , j , k ); } } } }
あと、aとbの使用頻度は低いのに、これがプライム変数に割り当てられているのが気になります。
なんとか、iとjに置き換えられないでしょうか。
ということで、このようにします。
public void foo( int i , int j ){ int a = i; int b = j; int k; for( i = a - 1 ; i >= 0 ; i=i-1 ){ for( j = b - 1 ; j >= 0 ; j=j-1 ){ for( k = 9 ; k >= 0 ; k=k-1 ){ something( i , j , k ); } } } }
引数をループ変数にしてやります。
これでかなり速くなりました。わーい。
……ん〜、なんかテンションが低い……なんでだろ。