Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 性能+;=在爪哇_Java_Performance_Compilation_Addition - Fatal编程技术网

Java 性能+;=在爪哇

Java 性能+;=在爪哇,java,performance,compilation,addition,Java,Performance,Compilation,Addition,背景 最近,我发布了一个答案,建议如下: x = x + 2; 有人评论说:“请改用x+=2;。” 在对汇编语言和编译器进行了一定程度的研究之后,我一直认为这两条语句将简化为相同的汇编指令。因此,我也认为两者之间不会有性能差异,唯一的差异是意见和风格的问题 收到上面的评论后,我很好奇,在谷歌上快速搜索了一下,结果一无所获 我的问题 x=x+2之间是否存在性能差异和x+=2?或者是可读性和风格上的唯一区别,使两者之间的选择成为一个意见问题 请提供证据,而不是意见。编译器以相同的方式执行两条语句,

背景

最近,我发布了一个答案,建议如下:

x = x + 2;
有人评论说:“请改用
x+=2;
。”

在对汇编语言和编译器进行了一定程度的研究之后,我一直认为这两条语句将简化为相同的汇编指令。因此,我也认为两者之间不会有性能差异,唯一的差异是意见和风格的问题

收到上面的评论后,我很好奇,在谷歌上快速搜索了一下,结果一无所获

我的问题

x=x+2之间是否存在性能差异和
x+=2
?或者是可读性和风格上的唯一区别,使两者之间的选择成为一个意见问题


请提供证据,而不是意见。

编译器以相同的方式执行两条语句,执行时间或性能没有任何差异
x+=2
被编译器解释为x=x+2,在执行时间上应该没有区别。

我认为唯一的区别是可读性。在课堂上学习时,我们被告知
x+=2
实际上不太常见

这个问题的答案似乎表明它取决于您使用的编译器,公认的答案是,对于大多数编译器,它是相同的


这个问题是针对Java的,并提供了更多的证据。

下面是Eclipse编译器的工作(请参见下面的编辑)

Java代码:

public static void x( int x)
{
    x = x + 2;
}
public static void x( int x)
{
    x += 2;
}
字节码:

public static void x(int);
  Code:
     0: iinc          0, 2
     3: return
public static void x(int);
  Code:
     0: iinc          0, 2
     3: return
Java代码:

public static void x( int x)
{
    x = x + 2;
}
public static void x( int x)
{
    x += 2;
}
字节码:

public static void x(int);
  Code:
     0: iinc          0, 2
     3: return
public static void x(int);
  Code:
     0: iinc          0, 2
     3: return
如您所见,它们编译为相同的字节码。Java编译器会大量优化您的代码,所以不要试图为琐碎的事情对其进行优化,尤其是以牺牲可读性为代价


编辑:事实证明并非所有编译器都将这些语句编译成相同的字节码。然而,原来的观点仍然成立。不要试图为琐碎的事情优化Java代码,尤其是以牺牲可读性为代价;因为,JIT编译器在将字节码编译成本机机器码时会对代码进行大量优化,即使某些Java编译器跳过一些优化。

在我的机器上,这两段代码生成的字节码是不同的(很可能在你的机器上也是如此),但这并不重要。首先,优化后JVM实际运行的机器代码可能是相同的;第二,在实践中,你不会注意到任何区别。自己尝试基准测试(这解释了为什么不应该),比如说,在循环中,您将看到在运行和/或微小更改之后,您会得到各种不同的结果,这些结果可能相差n倍,并且在您尽可能预测的环境中发生。想象一下在真实代码中发生了什么,其中任何一行都不可能是一个巨大的CPU消耗者

为这段代码运行一个合适的微基准表示它在两种变体中都会在3-4纳秒内运行(同时从字段加载初始值并从方法返回结果,否则整个方法可能会被丢弃)。我有点怀疑某些框架是否可以在我的桌面上如此精确地测量时间,但我确实认为这是真的,或者这两段代码的实际计时淹没在其他成本中(调用方法?加载值?返回值?)

为了完整性,我使用的基准是

import org.openjdk.jmh.annotations.*;
import java.util.concurrent.*;

@State(Scope.Thread)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class MyBenchmark {

    public int a = 0xDEADBEAF;

    @Benchmark
    public int f1() {
      int x = a;
      x += 2;
      return x;
    }

    @Benchmark
    public int f2() {
      int x = a;
      x = x + 2;
      return x;
    }
}

运行10次预热迭代,10次测量迭代,3次分叉。

您在这里担心的是纳秒。过早的优化。一个简单的“为什么?”作为对那个评论的回答会更有效率。你的代码是
x=(x+2)我的评论不是关于性能,而是关于可读性(因为它还避免了多余的括号)。@JimGarrison我不想更改代码库中的所有语句,我想获得理论上的理解。你可以用Java编写它,编译它并反编译字节码以获得所需的证据。有证据吗?我在帖子中找到了。Q&A是针对C的。Java编译器对
+=
的处理方式不同。这可能不会影响性能,但有一点不同。我说的是:有没有证据表明编译器对待它们是一样的?“实际上不太常见”我怀疑。。。非常好。@Tom我上了一所好的工程大学,我和我的大多数朋友都没有写过简单整数加法的+=;我们认为它不那么可读。“汤姆,老实说,我不记得教授是在现实世界里还是在系内谈论,但是X= X + 1当然更直观,因此可能更受学生欢迎。”Sav扫帚“更受学生欢迎”。我同意这一点,而且最好先教
x=x+1
,特别是如果学生以前从未编程过。你使用的是什么版本的java?这两个语句的字节码不同,我使用的是1.7.0_51版。您使用的是什么版本?我使用的是1.8.0_101版本。是的,1.8.0_101似乎生成了一个不同的字节码,其中包含x=x+2的3条指令。实际上,1.7.0_51似乎也生成了与1.8.0_101相同的字节码。为两种不同样式生成相同字节码的是Eclipse编译器。很抱歉给你带来了困惑。