У меня есть некоторый код Java, который выполняет побитовые операции над BitSet. У меня есть список операций, и я могу «интерпретировать» их, зацикливая их, но для меня важно, чтобы я мог выполнять эти операции как можно быстрее, поэтому я пытался динамически генерировать код для их применения. Я генерирую исходный код Java для выполнения операций и компилирую класс, реализующий эти операции, используя Javassist.
К сожалению, мой динамически сгенерированный код работает медленнее, чем интерпретируемый код. Похоже, что это происходит потому, что HotSpot оптимизирует интерпретируемый код, но не оптимизирует скомпилированный код: после того, как я запустил его несколько тысяч раз, мой интерпретированный код работает в два раза быстрее, чем вначале, но мой скомпилированный код не показывает ускорения. В соответствии с этой гипотезой мой интерпретируемый код изначально медленнее скомпилированного кода, но в конечном итоге быстрее.
Я не уверен, почему это происходит. Я предполагаю, что, возможно, 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();
Кто-нибудь имеет представление о том, что здесь происходит? Я бы очень признателен за любую помощь, которую вы можете оказать.
Я использую серверную виртуальную машину Sun 1.6 в 32-разрядной версии Windows XP.