为啥算术赋值运算符更有效? [复制]

Posted

技术标签:

【中文标题】为啥算术赋值运算符更有效? [复制]【英文标题】:Why are arithmetic assignment operators more efficient? [duplicate]为什么算术赋值运算符更有效? [复制] 【发布时间】:2013-11-26 05:59:01 【问题描述】:

速记 Java 算术运算符的一个示例是 a += 4; 代表 a=a+4;

在 The Complete Reference, Java 2 中,Herbert Schildt 提到“它们在 Java 运行时系统中的实现效率高于同类产品”

是什么让它的实现比a=a+4;更高效

【问题讨论】:

尝试为每个生成字节码并进行比较。如果您不知道如何比较它们,请将它们发布在您的问题中,这里有人会帮助您。 我认为它实际上被称为复合赋值运算符,对吧? @ZongZhengLi 是的,同一个东西,在不同的文献中有不同的名字提到 @LuiggiMendoza 如何生成/查看字节码? @anakin 你也可以在这里查看 [***.com/questions/9292383/… 【参考方案1】:

只有微基准可以在任何给定的执行环境中确认或拒绝作者的主张。

在现代 JVM 上,这两个版本很有可能表现出相同的性能。

附:如果书名中的“2”与“Java 2”中的一样,我强烈建议您购买更新的书!

【讨论】:

【参考方案2】:

a+=4 :它提供隐式类型转换。 例如考虑 a+=4.4 它会自动将 4.4 转换为 4。 但是 a = a+4.4 会给你投射错误。

【讨论】:

对我来说,这个论点听起来像是在声称 a=a+4 更快,因为它假定了正确的类型。【参考方案3】:

与一元增量运算符 (++) 一样,两个版本在性能方面是相同的,因为它们生成相同的字节码(至少使用 Eclipse JDT)。

【讨论】:

【参考方案4】:

对于a += 4 javac 可以产生IIC 指令,该指令通过常量增加局部变量。它理论上比IADD更有效。

IADD 确实 Add int 从堆栈中弹出两个值,然后推回结果。 IIC 在堆栈上什么都不做,只是增加局部变量。

因此,如果您可能使用非常有限且原始的 JVM,就像您在 Java Card 上发现的那样,这可能很重要,但在 %99.9 的场景中它并不重要。 Java、JVM 和大多数其他虚拟机都取得了长足的进步。

顺便说一句,你用的是哪个版本的书? Amazon 提到它将在 2014 年发布第 9 版。如果这句话还在书中,我会感到惊讶。

【讨论】:

你是认真的吗? a+=10 更快,java 在编译时无法优化? @Cruncher 我的后期编辑是否可以作为答案? 我的问题更多的是编译时优化,而不是运行时。如果a+=4 更快,为什么不自动编译a=a+4 到它(即为仅此行不同的2 个程序生成相同的字节码)?对于编译器来说,这似乎是一个相当微不足道的优化。 @Cruncher 自己做一个实验,对我来说javac 1.6 没有优化它。它在某种程度上是 JIT 的缺点。编译器创建非常简单的代码,Java 生态系统依赖于 JIT 来改进运行时的代码。几年前,那里有关于为什么开发人员应该编写转储代码的明确文章 (oracle.com/technetwork/articles/javase/devinsight-1-139780.html) - 我认为 javac 遵循相同的原则并创建愚蠢的代码。

以上是关于为啥算术赋值运算符更有效? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥短原语有赋值运算符(&=、+=)但没有非赋值运算符(&、+)? [复制]

为啥我能够为 QObject 子类创建复制构造函数并重载赋值运算符?

Python算术运算符赋值运算符关系运算符逻辑运算符条件运算符(三元运算符)

为啥我们在重载赋值中使用 return *this? [复制]

算术和关系运算符

Python运算符 ( 算术运算符 | 赋值运算符 )