スポンサード リンク

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

スポンサード リンク
-- : -- : -- | スポンサー広告 | page top↑
スポンサード リンク

式の計算結果を一時変数に格納することによるパフォーマンスの向上

不変クラスとして設計した複素数クラスComplex(Javaによる実装)」に対して、
>div()において、あらかじめ分母(c.re*c.re + c.im*c.im)を計算して一時変数denominatorに格納しているのは、この計算を2度行うとパフォーマンスが低下するためです。このように、複数回オブジェクトを参照する場合はその値を一時変数に格納することでパフォーマンスが向上します。

これですが、これは本当ですか? 最適化処理の段階でまとめられたりはしないんですか?パフォーマンスが向上しますというのであればちゃんと実験して検証すべきだと思います。
とのコメントをいただいたので、これを検証してみました。
Complexクラスに新たにメソッドnaive_div()を追加するとともに、Complexの内部クラスとしてテスト用のクラスComplexPerformanceTestを実装しました。これを5回実行し、次に c1.naive_div(c2); を c1.div(c2); に書き換えて5回実行し、それぞれの実行時間を計測することでパフォーマンスの比較を行いました。

メソッドnaive_div()

/* こちらの方が遅いと予測される。*/
public Complex naive_div(Complex c) {
  return new Complex(
    (re*c.re + im*c.im)/(c.re*c.re + c.im*c.im),
    (im*c.re - re*c.im)/(c.re*c.re + c.im*c.im));
}

メソッドdiv()

/* こちらの方が速いと予測される。*/
public Complex div(Complex c) {
  double denominator = c.re*c.re + c.im*c.im;
  return new Complex((re*c.re + im*c.im)/denominator,
    (im*c.re - re*c.im)/denominator);
}

テスト用のクラス

class ComplexPerformanceTest {
  
  public static void main(String args[]) {
    long start[] = new long[100];
    long stop[] = new long[100];
    long time[] = new long[100];
    
    for(int j=0; j<100; j++) {
      start[j] = System.currentTimeMillis();
      for(int i=0; i<1000000; i++) {
        Complex c1 = new Complex(1, 2);
        Complex c2 = new Complex(3, 4);
        c1.naive_div(c2);
      }
      stop[j] = System.currentTimeMillis();
    }
    for(int i=0; i<start.length; i++) {
      time[i] = stop[i] - start[i];
    }
    System.out.println(mean(time));
  }
  
  private static long mean(long l[]) {
    long sum = 0;
    for(int i=0; i<l.length; i++) {
      sum += l[i];
    }
    return sum/l.length;
  }
}

計測結果

計測結果は以下のようになりました。5回ともすべてnaive_div()よりdiv()の方が速かったという結果になりました。このようにオブジェクトの参照を含む式はJavaの最適化が働かないので、同じ計算結果になるとプログラマがわかっている場合はその値を一時変数に格納しておくことが有効です。

メソッド 1回目 2回目 3回目 4回目 5回目
naive_div() 192 193 192 193 190
div() 185 189 185 183 185

逆コンパイルによる検証

今回は実際にプログラムを動作させて実行時間を計測することによってパフォーマンスの比較を行いましたが、classファイルを逆コンパイルすることによって、コードがコンパイル時に最適化されているかどうか目で見ることができます。この方法による検証を別の記事に記しました。※実行時にJavaVMによってなされる最適化はこの方法では見ることができません。


スポンサード リンク

テーマ:プログラミング - ジャンル:コンピュータ - ソーシャルブックマーク: この記事をクリップ! Yahoo!ブックマークに登録

00 : 41 : 14 | プログラミング-Java | トラックバック(0) | コメント(0) | page top↑
<<Javaコンパイラに最適化されたコードを逆コンパイルしてみる | ホーム | 意外と知らない?Microsoft Officeの小技>>
コメント

コメントの投稿














管理者にだけ表示を許可する

トラックバック
トラックバックURL
http://networkprogramming.blog18.fc2.com/tb.php/113-ee549de4
この記事にトラックバックする(FC2ブログユーザー)
| ホーム |

プロフィール

TBVector

Author:TBVector

プロフィール

メールフォーム

記事検索

Google

最近の記事

人気の記事

過去の記事

カテゴリー

タグランキング

リンク

最近のコメント

最近のトラックバック

アクセスカウンタ

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。