这是在java中增加计数器(整数)的最佳方法。我对手术费用感兴趣。
int j = 0;
j = j + 1;
或
int i = 0;
i++;
它对于小程序几乎相同,但它对于大型计算,数千次迭代而言是不同的。
答案 0 :(得分:3)
根据发布的其他答案,我觉得你应该看到所有三种技术的实例。以下是高度情境化的,但是非正式演示可以发生的事情:
守则
#include <stdio.h>>
int i=1;
int main()
{
printf("i=%d\n", i);
printf("i++ : %d\n", i++);
printf("++i : %d\n", ++i);
i = i + 1;
printf("i=i+1 : %d\n", i);
return 0;
}
工具
使用clang 3.3优化设置为-O2
大会清单
清理并注明消费:
; Basic printf()
movl _i(%rip), %esi
leaq L_.str(%rip), %rdi
xorb %al, %al
callq _printf
; post-increment (i++)
movl _i(%rip), %esi
leal 1(%rsi), %eax
movl %eax, _i(%rip)
leaq L_.str1(%rip), %rdi
xorb %al, %al
callq _printf
leaq L_.str2(%rip), %rdi
; pre-increment (++i)
movl _i(%rip), %esi
incl %esi
movl %esi, _i(%rip)
xorb %al, %al
callq _printf
leaq L_.str3(%rip), %rdi
; traditional (i = i + 1)
movl _i(%rip), %esi
incl %esi
movl %esi, _i(%rip)
xorb %al, %al
callq _printf
差异
在i
vs i++
的情况下,在增加之前存储包含++i
的先前值的临时值。这只是 因为所谓的temp用作printf()
函数调用的参数。另请注意,在预增量和传统机制中,生成的优化程序集相同(movl, incl, movl
)。
如果后增量操作未评估,它会有所不同吗?
int main()
{
i++;
printf("i=%d\n", i);
++i;
printf("i=%d\n", i);
i = i + 1;
printf("i=%d\n", i);
return 0;
}
由此产生的组装是:
; post-increment
movl _i(%rip), %esi
incl %esi
movl %esi, _i(%rip)
leaq L_.str(%rip), %rbx
movq %rbx, %rdi
xorb %al, %al
callq _printf
; pre-increment
movl _i(%rip), %esi
incl %esi
movl %esi, _i(%rip)
movq %rbx, %rdi
xorb %al, %al
callq _printf
; traditional
movl _i(%rip), %esi
incl %esi
movl %esi, _i(%rip)
movq %rbx, %rdi
xorb %al, %al
callq _printf
请注意,您看到的rbx
魔法是无关的,只是缓存printf()
的共享格式字符串的方法。在所有三种情况下,使用相同的代码(movl,incl,movl
)。
<强>结论强>
对于独立语句,clang 3.3会将所有三个优化为相同的结果代码。如果引入评估依赖性,则后增量和预增量可以(并且可能会)发出不同的代码。如果您的增量是一个独立的声明,那么您选择的没有任何区别。
答案 1 :(得分:2)
使用前缀运算符比使用postfix更快。即++i
比i++
快。
对于++i
,值会增加并返回新值。
对于i++
,值会增加,但会返回旧值。性能差异来自于需要首先存储较旧的值。
答案 2 :(得分:1)
不确定第一种方法,因为我从未以这种方式递增计数器(我相信其他人会进来)但是对于第二种方法,最好使用++ i而不是i ++。原因已经回答了那个in this question,但简而言之,i ++制作了i的副本,而++我直接在变量本身上工作。
答案 3 :(得分:1)
当你谈到增量或减量时,首先想到的是用于递增或递减的运算符,即++, -
在你的第一个案例当然会为你做增量工作,但它的增量技术间接方法,编译器需要做两个工作,1)增加2)分配。
在第二个编译器中,编译器知道它是递增运算符,因此它将递增该变量。
答案 4 :(得分:1)
++i
比其他方法更快。
所以你的代码将是:
int i = 0;
++i;
答案 5 :(得分:1)
以下是一些Java源代码:
int i = 0;
i = i + 1;
i += 1;
++i;
i++;
这是相应的Java字节代码,由javap -c
:
0: iconst_0
1: istore_1
2: iload_1
3: iconst_1
4: iadd
5: istore_1
6: iinc 1, 1
9: iinc 1, 1
12: iinc 1, 1
如您所见,最后三个语法形式编译为相同的JVM指令iinc
。第一个产生更多的字节代码,但如果JIT编译器没有优化这种差异,我会感到惊讶。
答案 6 :(得分:0)
@Modred:对于你引用的两种方法的使用,在影响的情况下结果是不一样的。 对于以下代码,结果不一样:
int i = 0, j = 0,k = 0;
cout << "i = " << i << " ,j = " << j << " ,k = " << k << '\n';
j = i++;
cout << "i = " << i << " ,j = " << j << " ,k = " << k << '\n';
k = ++i;
cout << "i = " << i << " ,j = " << j << " ,k = " << k << '\n';
<强>输出强>
i = 0 ,j = 0 ,k = 0
i = 1 ,j = 0 ,k = 0
i = 2 ,j = 0 ,k = 2