5

我正在做一个项目,在这个项目中我们正在生产一种可以编译为 java 的语言。我们使用的框架 (xtext) 在其生成的代码中大量使用了装箱。具体来说,如果您有如下声明:

int i = 1;
int j = 2;
int k = i + j;

然后编译后的代码如下:

IntegerExtensions.operator_plus(((Integer)i), ((Integer)j))

现在,在我正在从事的项目中,在某些情况下,特定的基本二进制操作将非常普遍(尤其是增量和比较)。

我的问题是:这会是性能方面的问题,还是 JIT(或类似的智能 JVM 功能)会简单地意识到正在发生的事情并解决所有问题?

发帖前请阅读:我对收到回复说“你不应该关心,让它可读”不感兴趣。这段代码是生成的,我根本不关心生成代码的可读性。我真正关心的是我们不会因此而对性能造成重大影响。

谢谢

4

4 回答 4

4

这实际上会产生影响。当转换为Integer发生时,它将转换intInteger使用Integer.valueOf(int n)方法。此方法将检查该值是否在缓存范围内(-128 到 127),如果不在,它将创建new Integer(n)

影响的程度可能很大也可能很小,您必须自己测试。

于 2011-12-11T23:16:11.030 回答
3

说它会导致性能问题取决于您所说的问题。你所说的问题可能取决于代码将解决什么样的问题。

此答案中有一个部分对其进行了总结,并提供了指向 Autoboxing 指南的链接,其中提到:

对于科学计算或其他对性能敏感的数字代码,不适合使用自动装箱和拆箱。

这是一个特定示例,其基准集中在 int/Integer 自动装箱

简单的问题:int/Integer 类型的自动装箱有多贵?

简单的答案:每个拳击 15 纳秒。

于 2011-12-11T23:15:52.350 回答
3

根据我的经验,有几点意见:

  1. 装箱通常降低应用程序的性能。它的显着程度取决于所实现算法的性质。是否值得修复,只有分析器和您的预期成本效益比才能告诉您。

  2. 装箱通常增加应用程序的内存使用量。就我而言,这非常重要——可能比性能更重要。

    Java 中的int32 位范围占用 4 到 8 个字节(取决于 JVM 实现)的内存。AnInteger在 64 位系统上将占用 20 到 24 个字节 - 您仍然需要对它的引用。对于处理大型数组的应用程序,可以轻松地将其内存需求增加四倍(x4) - 或者更糟。

    在这种情况下,拳击可以区分“它可以工作”和“它不工作” - 在给定的计算机上你只能拥有这么多的内存。性能甚至没有进入讨论范围,尽管内存不足的应用程序通常也会变慢。

也就是说,对象确实有一个有用的优势:通过使用null.

于 2011-12-11T23:40:25.190 回答
1

简单地说:测试它。

制作一个简单示例的两个版本并测量它所花费的时间。然后,您将知道性能的确切差异以及您是否负担得起。

于 2011-12-11T23:15:58.187 回答