【发布时间】:2015-11-18 23:38:05
【问题描述】:
我有一个不寻常的要求:我的应用程序从一个很长的脚本(用动态类型语言编写)自动生成 Java 代码。脚本太长了,我打了the maximum method size of 65k of the JVM。
该脚本仅包含关于原始类型的简单指令(除了数学函数之外,不调用其他函数)。它可能看起来像:
...
a = b * c + sin(d)
...
if a>10 then
e = a * 2
else
e = a * abs(b)
end
...
... 转化为:
...
double a = b * c + Math.sin(d);
...
double e;
if(a>10){
e = a * 2;
}else{
e = a * Math.abs(b);
}
...
我克服方法大小限制的第一个想法如下:
- 将所有局部变量变成字段
- 在单独的方法中每 100 行(如果需要 if/else 块,则可以更长)拆分代码。
类似:
class AutoGenerated {
double a,b,c,d,e,....;
void run1(){
...
a = b * c + sin(d);
...
run2();
}
void run2(){
...
if(a>10){
e = a * 2;
}else{
e = a * Math.abs(b);
}
...
run3();
}
...
}
您知道其他更有效的方法吗?请注意,我需要代码尽可能快地运行,因为它将在长循环中执行。我不能求助于编译到 C,因为互操作性也是一个问题......
我也很感激指向可能对我有帮助的库的指针。
【问题讨论】:
-
如果担心效率问题,请注意,超过 8 KB 的方法默认不会编译。
-
我会考虑内联可以为您做什么。是否有任何重复的代码序列在内联后会产生相同的代码?
-
@PeterLawrey,超过 8KB 会发生什么?代码是否被解释,效率很高?是什么让编译器决定它应该编译什么?关于inlining,它究竟是如何工作的?我应该在代码中寻找“模式”并创建专门的方法来处理它们吗?
-
如果方法没有被编译,它将被解释。通过内联,我建议为您在生成的代码中使用的常见功能编写一些小方法。
-
如果我是你,我会认真考虑@OldCurmudgeon 的答案。你说它需要尽可能快地运行,但我总是会质疑这样的假设,因为它很大程度上取决于那个长循环中发生的任何其他事情。如果这段代码即使在被解释的时候也只占总数的 20%,那么编译它就不能节省更多,而且很可能你在其他地方有更大的“炸鱼”。
标签: java jvm code-generation auto-generate