我正在开发一个项目,我们正在编写一个编译成java的语言。我们使用的框架(xtext)在其生成的代码中大量使用了拳击。 具体来说,如果您有如下声明:
int i = 1;
int j = 2;
int k = i + j;
然后编译的代码如下:
IntegerExtensions.operator_plus(((Integer)i), ((Integer)j))
现在,在我正在研究的项目中,某些情况下特定的基本二进制操作将非常普遍(特别是增量和比较)。
我的问题是:这在性能方面会出现问题,还是JIT(或类似的智能JVM功能)只是意识到发生了什么并解决了所有问题?
请在发布之前阅读:我对收到回复说“你不应该关心,让它变得可读”不感兴趣。生成此代码,我根本不关心生成的代码的可读性。我所关心的是,我们不会因此受到重大影响。
由于
答案 0 :(得分:4)
这实际上可能会产生影响。当投射到Integer
时,它会使用int
方法将Integer
转换为Integer.valueOf(int n)
。此方法将检查该值是否在缓存范围内(-128到127),如果不是,则会创建new Integer(n)
影响的数量可能很多或很少,你必须自己测试。
答案 1 :(得分:3)
说导致性能问题取决于您所谓的问题。你所谓的问题可能取决于代码将要解决的问题类型。
this answer中有一个部分对其进行了总结,并提供了一个指向Autoboxing指南的链接,其中提到:
将自动装箱和拆箱用于科学计算或其他对性能敏感的数字代码是不合适的。
这是一个specific example with benchmarks focusing on int/Integer autoboxing
简单问题:int / Integer类型的自动装箱有多贵?
简单回答:每拳击15纳秒。
答案 2 :(得分:3)
根据我的经验得出的一些观察结果:
通常的拳击会降低应用程序的性能。它的明显程度取决于所实现算法的性质。是否值得修复,哪里只是一个分析器,你的预期成本效益比可以告诉你。
通常的装箱会增加应用程序的内存使用量。就我而言,这是非常重要 - 可能比表现更重要。
Java中的int
占用32位范围内存的4到8个字节(取决于JVM实现)。 Integer
在64位系统上占用20到24个字节 - 您仍然需要对它进行引用。对于处理大型数组的应用程序,它可以轻松地使其内存需求翻两番(x4) - 或者更糟。
在这种情况下,拳击可以区分“它工作”和“它不起作用” - 在给定的计算机上只有这么多的内存。性能甚至没有进入讨论,但是,内存不足的应用程序通常也会变慢。
也就是说,对象做有一个有用的优势:使用null
有一种本地方式可以说“没有价值”。
答案 3 :(得分:1)
简单地说:测试一下。
制作一个简单示例的两个版本并测量所需的时间。那么你就会知道表演的确切差异以及你是否能负担得起。