同意する、レッスンは結果からの喜びよりも多くの頭痛をもたらします。 たぶんあなたはantlrまたはjavaccライブラリーに精通しているのであれば、少し血を流すでしょう。 しかし、最も遠いパッケージのpr索好きな目からできるだけ早く隠すthatい生成されたクラスからテールを取得します。
昨日cglibについて書いて 、ドキュメントのバイトコードの変更に関する章に気付きました。 そして、疑問が自然に発生します:クラスが望んでいるものではなく、実行中にクラスを強制的に実行させることは可能ですか?
私は正直にドキュメントの研究を始め、すぐに人気のあるasmバイトコードエディタに行きました。 ただし、残念ながら、バイトコードを十分に理解し、理解することによってのみ変更できます。 より正確には、これは、実行結果「x * x + x / 2」を返す必要がある場合、この式を命令でコンパイルする必要があることを意味します。
コンパイラを書きたくないのですが、それでも私はグーグルへのリクエストを作成し、 探しているものを見つけました
幸いなことに、このようなコンパイラはすでに別のjavassistバイトコードエディタに実装されています 。 ちなみに、javassistのドキュメントは充実していますが、オープンソースコミュニティでは、cglibの方がはるかに高速であるという意見があります。 この場合、クラスの作成速度は、そのメソッドの実行速度ほど重要なコンポーネントではありません。 だから何をする必要があります:
Copy Source | Copy HTML public interface Evaluator { public double eval( double x); }
クラスの作成:
Copy Source | Copy HTML
- ClassPoolプール= ClassPool.getDefault();
 - CtClass evalClass = pool.makeClass( "Formula" );
 - evalClass.setInterfaces(
 - 新しい CtClass [] {
 - pool.makeClass( "com.micro.bench.Evaluator" )
 - });
 - 文字列式= "x * x + x / 2" ;
 - evalClass.addMethod(
 - CtNewMethod.make(
 - "public double eval(double x){return(" + expession + ");}" 、
 - evalClass));;
 - クラスclazz = evalClass.toClass();
 - runtime =(評価者)clazz.newInstance();
 
それだけです! 私たちの手には、Evaluatorインターフェイスを実装するクラスのオブジェクトがあり、x * x + x / 2を返します。
さて、今ではパフォーマンスを比較するのがいいでしょう。 コメントをくれたTheShadeに感謝し、Timerを少し変更してテストに使用しました。 両方のメソッドが同時に実行されることを示すテスト結果:
     合計| 金額| 最後| 最後の5 | 最後の10 | 平均|  dev | 操作
    6856.00 |  20.00 |  351.00 |  343.00 |  341.00 |  342.80 |  1.24 |  ..ランタイム計算
    6874.00 |  20.00 |  337.00 |  343.00 |  344.00 |  343.70 |  1.03 |  ..コンパイル時の計算
      - 合計-合計ms
 - amount-開始数
 - last-最後のms
 - 過去5-過去5ミリ秒の開始時の平均
 - last 10-過去10ミリ秒の開始時の平均
 - avg-一般的なミリ秒の平均
 - dev-偏差
 
クラスEvaluation.java-2つの方法の比較
クラスTimer.java-速度と統計の測定