2009-05-17 5 views
2

BitSetでビット単位の操作を実行するJavaコードがあります。私は操作のリストを持っていて、それらをループして解釈することができますが、できるだけ早くこれらの操作を実行できることが重要です。そのため、コードを動的に生成して適用しています。私は操作を実行するJavaソースを生成し、Javassistを使用してこれらの操作を実装するクラスをコンパイルします。オペレーションを実行するために生成されたJavaコードが「インタプリタループ」より遅く実行されるのはなぜですか?

残念ながら、私の動的に生成されたコードは、解釈されたコードよりも遅く実行されます。これは、HotSpotが解釈済みコードを最適化しているが、コンパイル済みコードを最適化していないためです。数千回実行した後、私の解釈済みコードは最初の2倍の速さで実行されます。この仮説と一致して、私の解釈されたコードは最初はコンパイルされたコードよりも遅いですが、結局はより高速です。

なぜこれが起こっているのか分かりません。私の推測では、JavassistがクラスHotSpotが触れないクラスローダーを使用している可能性があります。しかし、私はJavaのクラスローディングについて専門家ではないので、これが合理的な推測か、それをテストする方法についてはわかりません。ここでは、私はJavassistの持つクラスを作成し、ロードしています方法は次のとおりです。

ClassPool pool = ClassPool.getDefault(); 
CtClass tClass = pool.makeClass("foo"); 

// foo implements MyInterface, with one method 
tClass.addInterface(pool.get(MyInterface.class.getName())); 

// Get the source for the method and add it 
CtMethod tMethod = CtNewMethod.make(getSource(), tClass); 
tClass.addMethod(tMethod); 

// finally, compile and load the class 
return (MyInterface)tClass.toClass().newInstance(); 

誰もがここで何が起こっているかのようなアイデアを持っていますか?私は本当にあなたが与えることができる何かを助けていただければ幸いです。

Windows XP 32ビット版のSun 1.6サーバーJVMを使用しています。

+0

多くのメソッド呼び出しに関連するタイミングについては、クラスのビルディングを含めて* NOT *であることを確認していますか? –

+0

@mP - はい、私は、このクラスを実行するのにかかる時間を計時しています。コンパイル時間とその他は含みません。 –

答えて

3

HotSpotはコードがどこから来るかには関係ありません。たとえば、別のクラスローダーによってロードされた実装を使って、仮想メソッド呼び出しを通じて呼び出されるコードをうれしくインライン化します。

このベンチマークで実行しようとしている操作をソースコードで書き出し、それをベンチマークすることをお勧めします。とにかくジェネレータを書くのではなく、生成されたコードの例を書く方が簡単です。

HotSpotがコードをハードに最適化しない理由はいくつかあります。例えば、非常に長いメソッドはインライン化されないか、メソッドがインライン化されない傾向があります。

+0

ヒントをありがとう、トム。クラスローダーとは関係がないことを確認できます。私は生成されたコードをテキストファイルに吐き出し、普通のクラスのようにコンパイルし、同じパフォーマンスを得ました。たぶん、インライン展開を防ぐメソッドの長さと関係があります。私はそれと一緒に遊んで見てみましょう。 –

1

私はここで何が起こっているのか分かりました。私の最初の間違いは、長すぎる方法を生み出すことでした。私はそれを修正した後、生成されたコードはまだ遅いものの、最終的には解釈されたコードの速度に近づいていることに気付きました。

私は、ここで最大のスピードアップは、私のコードを最適化するHotSpotから来ていると思います。解釈されたバージョンでは、最適化するコードはほとんどないので、HotSpotはすぐにそれを処理します。生成されたバージョンでは、最適化するコードがたくさんあるので、HotSpotはすべてのコードに対して魔法を働かせるのに時間がかかります。

ベンチマークを十分に実行すると、生成されたコードが解釈されたコードよりわずかに優れているのがわかります。

1

-XXコンパイルする必要がありますどのくらいの速コードを制御するJVMの設定があります:メソッド呼び出しのCompileThresholdは= 10000

数/コンパイルする前に支店[-client:1500]

Iあなたの例では、サイズが重要な役割を果たすように見えるので、これが役立つかどうかは分かりません。

関連する問題