обновление байтового кода во время выполнения в java и производительность - PullRequest
0 голосов
/ 16 сентября 2018

У меня есть некоторый очень критичный к производительности код, который на высоком уровне принимает кучу решений, выполняя некоторые сравнения с плавающей запятой или простые предикаты. Код может быть написан в виде дерева решений. По сути, каждый узел выполняет предикатную проверку, а затем решает, какой путь выбрать, пока не достигнем какого-либо конечного узла.

Чтобы повысить производительность вместо того, чтобы иметь это дерево решений, я генерирую некоторые блоки кода if-else, которые компилируются при запуске программ (в основном я генерирую код для всего дерева решений, поскольку заранее знаю предикаты). Это немного улучшает производительность. Теперь следующая оптимизация, которую я хочу сделать, это изменить код во время выполнения, то есть в старом мире без генерации кода и наличия деревьев решений с узлами, я мог бы скопировать дерево и закорачивать / перепрыгивать через некоторые узлы, следовательно, сжимая дерево и сделал общий расчет быстрее. Но в мире сгенерированного кода есть какой-либо инструмент, который может достичь того же самого путем изменения моего сгенерированного кода if-else на основе некоторых частичных данных времени выполнения, доступных во время вычислений. Также каковы последствия производительности изменения кода времени выполнения.

Ответы [ 2 ]

0 голосов
/ 16 сентября 2018

Это то, что я использую https://github.com/OpenHFT/Java-Runtime-Compiler для

, например

// dynamically you can call
String className = "mypackage.MyClass";
String javaCode = "package mypackage;\n" +
                 "public class MyClass implements Runnable {\n" +
                 "    public void run() {\n" +
                 "        System.out.println(\"Hello World\");\n" +
                 "    }\n" +
                 "}\n";
Class aClass = CompilerUtils.CACHED_COMPILER.loadFromJava(className, javaCode);
Runnable runner = (Runnable) aClass.newInstance();
runner.run();

Я предлагаю использовать известный интерфейс, который не меняется, вы можете позвонить, и ваш сгенерированный код реализует интерфейс.

Это не поддерживает перезагрузку класса, но вы можете каждый раз генерировать новое имя класса или каждый раз использовать другой загрузчик классов.

0 голосов
/ 16 сентября 2018

Прежде всего, JVM не позволяет вам изменять работающий код. Это позволяет вам генерировать новый код во время выполнения и загружать его.

  • Вы можете сделать это, сгенерировав исходный код и скомпилировав его, как вы это делали.
  • Вы можете сделать это на уровне байт-кода; например используя что-то вроде BCEL; см https://commons.apache.org/proper/commons-bcel/manual/bcel-api.html.

Кроме того, существует проект, спонсируемый Oracle (GraalVM), в котором (если я правильно понимаю) вы можете создавать (Truffle) AST и иметь структуру, которая позаботится о генерации кода. (В настоящий момент он кажется экспериментальным и может быть еще не готов к использованию.).


Кроме того, как влияет производительность на изменение кода времени выполнения.

Это вопрос за $ 65 536!

Одним из следствий этого является то, что каждый раз, когда вы изменяете код (путем его регенерации), метод должен перезагружаться и (для обычной JVM) снова проходить фазы интерпретации и компиляции JIT. И потенциально де-оптимизация / повторная оптимизация другого кода, который зависит от модифицированного кода.

Это не будет дешево. Я предполагаю порядка десятков или сотен тысяч собственных инструкций на метод , каждый раз, когда вы делаете это.


Теперь следующая оптимизация, которую я хочу сделать, это изменить код во время выполнения ...

OK. Поэтому я думаю, что на самом деле было бы лучше сделать более сложную генерацию кода.

Но также имейте в виду, что JIT-компилятор будет оптимизировать ваши сгенерированные байт-коды, выполняя такие вещи, как предсказание переходов на основе статистики, собранной во время интерпретации метода (до компиляции JIT).

Я бы также посоветовал опробовать некоторые из ваших оптимизаций вручную и сравнить их перед тем, как приступить к реализации собственного оптимизатора.

...