Java – 如何克服自动生成的代码中的最大方法大小

前端之家收集整理的这篇文章主要介绍了Java – 如何克服自动生成的代码中的最大方法大小前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我有一个不寻常的要求:我的应用程序从一个非常长的脚本(用动态类型语言编写)自动生成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,因为互操作性也是一个问题……

我也很感谢能够帮助我的图书馆指南.

最佳答案
我们在其中一个项目中使用了类似的方法,尽管其他人提到了它的缺点.我们用@ Marco13建议的单一启动器方法调用多个生成方法.我们实际上(非常精确地)计算生成的字节码的大小,并且仅在达到限制时才启动新方法.我们转换为Java代码的数学公式可以作为AstTree使用,我们有一个特殊的访问者,它计算每个表达式的字节码长度.对于这样简单的程序,它在Java版本和不同的编译器中非常稳定.因此,我们不会创建超出必要的方法.在我们的例子中,很难直接发出字节码,但您可以尝试使用ASM或类似的库为您的语言执行此操作(当然,这样,ASM将为您计算字节码长度).

我们通常将数据变量存储在单个double []数组中(我们不需要其他类型)并将其作为参数传递.这样你就不需要大量的字段(有时我们有数千个变量).另一方面,与索引高于127的字段访问相比,本地数组访问可能需要更多的字节码字节.

另一个问题是恒定的池大小.我们通常在自动生成代码中有许多双常量.如果声明了许多字段和/或方法,则它们的名称也会采用常量池条目.因此可以达到类常量池限制.有时我们会点击它并生成嵌套类来克服这个问题.

其他人也建议调整JVM选项.仔细使用这些建议,因为它们不仅会影响这个自动生成的类,还会影响其他每个类(我假设其他代码也在您的情况下在同一个JVM中执行).

原文链接:https://www.f2er.com/java/437180.html

猜你在找的Java相关文章