Я использую JavaCompiler для создания Java-класса, компиляции и загрузки в моем приложении.Почему JavaCompiler работает медленно при создании класса Java?
Моя проблема заключается в следующем: время выполнения с JavaCompiler намного медленнее, чем стандартный способ создания экземпляра того же класса.
Вот пример:
static void function() {
long startTime = System.currentTimeMillis();
String source = "package myPackage; import java.util.BitSet; public class MyClass{ static {";
while (!OWLMapping.axiomStack.isEmpty()) {
source += OWLMapping.axiomStack.pop() + ";";
}
source += "} }";
File root = new File("/java");
File sourceFile = new File(root, "myPackage/MyClass.java");
sourceFile.getParentFile().mkdirs();
Files.write(sourceFile.toPath(), source.getBytes(StandardCharsets.UTF_8));
// Compile source file.
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, sourceFile.getPath());
// Load and instantiate compiled class.
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() });
Class<?> cls = Class.forName("myPackage.MyClass", true, classLoader);
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println("EXECUTION TIME: " + elapsedTime);
}
После измерения этого кода, я создал новый класс Java с тем же содержанием вара источником для тестирования производительности: это намного быстрее, чем путь JavaCompiler , (Я не могу использовать стандартный класс, потому что в моем приложении мне нужно его динамически создавать). Итак, можно ли улучшить производительность этого кода? Или эта низкая производительность в норме?
EDIT: сгенерированный код, который я также испытал это простая последовательность OWLAPI аксиом:
package myPackage;
public class myClass{
static {
myPackage.OWLMapping.manager.addAxiom(myPackage.OWLMapping.ontology, myPackage.OWLMapping.factory.getOWLSubClassOfAxiom(/*whatever*/);
myPackage.OWLMapping.manager.addAxiom(myPackage.OWLMapping.ontology,myPackage.OWLMapping.factory.getOWLSubClassOfAxiom(/*whatever*/);
myPackage.OWLMapping.manager.addAxiom(myPackage.OWLMapping.ontology,myPackage.OWLMapping.factory.getOWLSubClassOfAxiom(/*whatever*/);
}
}
и это именно то, что переменная содержит источник. Число аксиом зависит от ввода пользователя.
Используйте 'StringBuilder' для' source' для цикла while. Компилятор не оптимизирует конкатенацию в цикле. – 4castle
@ 4castle Я сомневаюсь, что это сильно изменило бы ситуацию. – Kayaman
Я не вижу, чтобы вы создавали экземпляр класса здесь. Имейте в виду, что когда ваш код должен писать источник, скомпилируйте его на байт-код и _then_ загрузите его, в то время как обычно вы делаете только последний шаг. –