在Java和C++;?

在Java和C++;?,java,c++,performance,calculator,increment,Java,C++,Performance,Calculator,Increment,在java中,增加计数器(整数)的最佳方法是什么。我对手术的费用感兴趣 int j = 0; j = j + 1; 或 对于小型程序,它给出的结果几乎相同,但对于大型计算,数千次迭代,它却不同。不确定第一种方法,因为我从未以这种方式递增计数器(我相信会有其他人加入),但对于第二种方法,使用++I比使用++要好。原因已经得到了回答,但简单地说,i++复制了i,而++i直接作用于变量本身。不确定第一种方法,因为我从未以这种方式递增计数器(我相信会有其他人加入),但对于第二种方法,使用++i比使用i

在java中,增加计数器(整数)的最佳方法是什么。我对手术的费用感兴趣

int j = 0;
j = j + 1;


对于小型程序,它给出的结果几乎相同,但对于大型计算,数千次迭代,它却不同。

不确定第一种方法,因为我从未以这种方式递增计数器(我相信会有其他人加入),但对于第二种方法,使用++I比使用++要好。原因已经得到了回答,但简单地说,i++复制了i,而++i直接作用于变量本身。

不确定第一种方法,因为我从未以这种方式递增计数器(我相信会有其他人加入),但对于第二种方法,使用++i比使用i++更好。原因已经得到了回答,但简而言之,i++复制了i,而++i直接作用于变量本身。

当你谈论增量或减量时,首先想到的是用于增量或减量的运算符,即+++--

当然,在第一种情况下,这将为您完成增量工作,但它间接地使用增量技术,编译器将需要完成两项工作,1)加法2)赋值


在第二种情况下,编译器知道它是增量运算符,所以它会对该变量进行增量。

当您谈到增量或减量时,首先想到的是用于增量或减量的运算符,即+++--

当然,在第一种情况下,这将为您完成增量工作,但它间接地使用增量技术,编译器将需要完成两项工作,1)加法2)赋值


在第二种方法中,编译器知道它是递增运算符,因此它将递增该变量。

++i
比其他方法更快

因此,您的代码将是:

int i = 0;
++i;

++i
比其他方法更快

因此,您的代码将是:

int i = 0;
++i;

@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';

@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、 e
++i
i++

对于
++i
,该值将增加,并返回新值


对于
i++
,值会增加,但会返回旧值。性能差异是因为需要先存储较旧的值。

使用前缀运算符比使用后缀更快。i、 e
++i
i++

对于
++i
,该值将增加,并返回新值


对于
i++
,值会增加,但会返回旧值。性能差异来自于需要首先存储较旧的值。

与发布的其他答案不同,我觉得您应该看看所有三种技术的实际应用示例。以下内容是高度情景化的,但仍然说明了可能发生的情况:

代码

#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;
}
差异

#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;
}
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

结论


对于一个独立的语句,Clang3.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;
}
差异

#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;
}
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

结论


对于一个独立的语句,Clang3.3将优化所有三个语句,以获得相同的结果代码。如果引入求值依赖性,则增量后和增量前可能(并且很可能会)发出不同的代码。如果您的增量是一个独立的语句,那么您选择哪一个没有区别。

以下是一些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
像你一样