10

特定のデータ処理アルゴリズムを Java から C++ に移植中です。コードを書き直す理由は移植性であり、Java が使用できない環境で実行する必要があります。ただし、副次的な利点として、パフォーマンスの向上が期待されていました。

基本的に、このアルゴリズムは、相互へのポインターを持つオブジェクトで構成されるグラフからデータを読み取り、結果を計算します。計算中に多数のオブジェクトの割り当てが行われるため、おそらくこれが速度低下の原因です。問題は、C++ コードは現在、古い Java コードよりも約 10 倍速く実行されるということです。これは本当に予想外でした。おそらく50〜60%の改善が見られると思いました.

残念ながら、分析のためにここにコードを投稿する自由はありません。数千行なので、とにかく便利かどうかはわかりません。

問題は、アルゴリズムがほぼ同じであるということです。私が考えることができる唯一の大きな違いは、Javaには単一のスーパークラスの多くのドータークラスがあり、計算中に if(object.getClass() == daughterx.class) が何度も呼び出されるのに対し、C++コードでは一般的なものは1つだけですclass が使用され (ドータークラス間のコードの違いはほとんどないため)、単純な整数比較が使用されます。if(オブジェクト->タイプ== 15)

Java の Object.getClass() メソッドのコストはどれくらいですか? このメソッドが呼び出されると、低レベルで正確に何が起こっているのでしょうか?

4

3 に答える 3

14

Java の Object.getClass() メソッドのコストはどれくらいですか?

非主流のJVMでの実装方法に関する私の知識に基づいて、安価です

このメソッドが呼び出されると、低レベルで正確に何が起こっているのでしょうか?

通常 ...

  1. オブジェクトのヘッダーからクラス インデックスを抽出します (2 つまたは 3 つの命令)
  2. クラス インデックスからクラス記述子を検索します (2 または 3 命令)
  3. Classクラス記述子からオブジェクト参照をフェッチして返す(2 または 3 命令)

問題は、C++ コードは現在、古い Java コードよりも約 10 倍速く実行されるということです。

パフォーマンスのボトルネックは別の場所にあると思います。Java コードが遅い理由について結論を出す前に、Java コードのプロファイリングを試みる必要があります。

于 2012-09-01T06:46:46.290 に答える
8

10 倍の差が生じる可能性が最も高いのは、JVM が完全にウォームアップされていないことです。これを行わないと、Java でも 10 倍以上のパフォーマンスの違いが見られます。10,000 のバッチで実行してみて、最初の数回の実行は無視します。

public static void main(String... args) throws IOException {
    timeObjectGraph("First run", 1);
    timeObjectGraph("Second run", 2);
    timeObjectGraph("Next thousand", 1000);
    for (int i = 0; i < 5; i++)
        timeObjectGraph("Next ten thousand", 10000);
}

static int dontOptimiseAway = 0;

public static void timeObjectGraph(String desc, int runs) throws IOException {
    long start = System.nanoTime();
    for (int i = 0; i < runs; i++) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(out);
        oos.writeObject(Calendar.getInstance());
        oos.close();
        dontOptimiseAway = out.toByteArray().length;
    }
    long time = System.nanoTime() - start;
    System.out.printf("%s took an avg time of %,d ns%n", desc, time / runs);
}

版画

First run took an avg time of 37,509,488 ns
Second run took an avg time of 439,054 ns
Next thousand took an avg time of 185,242 ns
Next ten thousand took an avg time of 41,698 ns
Next ten thousand took an avg time of 19,981 ns
Next ten thousand took an avg time of 11,541 ns
Next ten thousand took an avg time of 13,451 ns
Next ten thousand took an avg time of 11,289 ns

最初の実行から最後の実行まで、パフォーマンスは 3000 倍向上しました

于 2012-09-01T07:04:41.900 に答える
5

パフォーマンスの違いの唯一の要因ではない可能性があります。残念ながら、コードが実際に何を行っているかをより完全に把握しなければ、何が起こっているのかを理解するのは非常に困難になります。

私の経験では、Java が C++ よりも 10 倍遅くなければならない理由はありません。おそらくプロファイラーから始めて、推測するのではなく、問題を理解するためにどこを指しているのかを確認します。

于 2012-09-01T06:16:08.233 に答える