【问题标题】:Analyzing the difference between i += 1 and i = i + 1 [duplicate]分析 i += 1 和 i = i + 1 之间的差异 [重复]
【发布时间】:2016-04-08 19:43:56
【问题描述】:
int i = 0;
i += 1;
i = i + 1;

这两个选项有什么区别?性能时间方面有哪些变化?哪个最厉害?

【问题讨论】:

  • 强制:i += 1i = i + 1 之间的选择绝对不会对程序的性能产生明显的影响。程序很慢,因为它们会创建数百万个对象、进行极其复杂的计算或等待服务器请求。

标签: java


【解决方案1】:

+= 进行隐式转换。例如这将编译:

int i = 0;
i += 1L;

这不会:

int i = 0;
i = i + 1L;

尝试在 Windows 8 上用我的 jdk1.8.0_11 编译这两个 sn-ps 并查看字节码差异...

0: iconst_0
1: istore_1
2: iinc          1, 1

对于i += 1 版本,并且:

0: iconst_0
1: istore_1
2: iload_1
3: iconst_1
4: iadd
5: istore_1

适用于i = i + 1 版本。

因此结论是:您可能确实获得了不同的字节码(或者可能不会,请参阅@TDG 答案)和不同的性能,但与您的程序将具有的其他开销相比,差异是微不足道的。

【讨论】:

  • 你能知道如何以 C# 的 IL 和 C++ 的汇编器等内部格式获取此代码吗?
  • @h.o.m.a.n 已添加到我的答案中
  • 你确定你有不同的字节码吗?我使用 jdk1.7.0_79 得到 i+=1i+=1Li=i+1 的相同字节码。
  • 是的。我确定。注意我已经用i += 1 进行了测试。 i += 1L 会产生不同的结果。而且我用的是jdk1.8.0_11。
【解决方案2】:

您必须考虑生成的汇编代码,生成的汇编代码完全取决于所使用的编译器。一些编译器会使这些差异不存在,因为它们会调整您的语句的性能。不过总的来说...

i += 1;

比..稍微高效一点。

i = i + 1;

因为“i”的地址在“i += 1”中只被访问过一次。它为您节省了一个通常没什么大不了的组装操作,除非您的计算可能通过多次迭代来完成。它可以为您节省一个汇编“mov”指令。

【讨论】:

  • 这是真的吗?处理器有操作“+=”吗?
  • 你真的检查了这两行的字节码,发现有什么不同吗?
  • 我同意。我认为即使处理器确实有操作“+=”,那么编译器也可能会检测到“i=i+1”并使用“+=”操作
  • 在汇编中,您将数据放入寄存器,然后执行操作。而不是做两个“mov”操作,你只需要一个。然后你对它执行一个操作。是的,一些程序集支持“inc”,它会将寄存器中的内容加一。
  • 可能会有智能编译器接受“i = i + 1”并将其转换为相同的程序集“i += 1”,或者更好的是“i++”
【解决方案3】:

接下来两个“程序”的Byte Code

//first "program"
int i = 0;
i = i + 1;

//second program
int i = 0;
i += 1;

是一样的:

0: iconst_0
1: istore_1
2: iinc          1, 1
5: return

当反编译上面的Byte Code时,我们得到了这个 -

int i = 0;
++i;

所以不管你用哪一个。

EDIT 以上是在 jdk1.7.0_79 和 Eclipse 3.8.2 上测试的。

【讨论】:

    【解决方案4】:

    i=i+1; 它将必须加载 i 的值,将其加一,然后将结果存储回 i

    i+=1; 加一,然后存储结果

    编辑1:有人说第二个(i+=1)更快,但是如果你在see C++(vs 2013)中反汇编这部分代码,你可以看到它们是一样的。不幸的是,我不知道如何在 JAVA 中制作它。

        i = i + 1;
    00AF52C5  mov         eax,dword ptr [i]  
    00AF52C8  add         eax,1  
    00AF52CB  mov         dword ptr [i],eax  
        i +=1;
    00AF52CE  mov         eax,dword ptr [i]  
    00AF52D1  add         eax,1  
    00AF52D4  mov         dword ptr [i],eax  
    

    【讨论】:

    • 好吧,只有当“添加一个”是少一个操作时,这才是正确的。是什么让你认为它是?实际上,即使是这样,编译器也可能会检测到“i=i+1”并使用“+=”操作
    • @TDG 你是对的
    • @VicSeedoubleyew 我不知道如何在 JAVA 中查看内部代码,但我知道如何在 C#(inner code IL) 和 C++(assembler) 中进行查看
    猜你喜欢
    • 2016-11-14
    • 2019-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    • 2015-05-24
    • 2014-02-22
    相关资源
    最近更新 更多