如果不使用结果值,i++和++i之间是否有性能差异?


当前回答

执行摘要:没有。

i++可能比++ I慢,因为I的旧值 可能需要保存以备以后使用,但实际上都是现代的 编译器将对其进行优化。

我们可以通过查看这个函数的代码来证明这一点, 都是++i和i++。

$ cat i++.c
extern void g(int i);
void f()
{
    int i;

    for (i = 0; i < 100; i++)
        g(i);

}

文件是一样的,除了++i和i++:

$ diff i++.c ++i.c
6c6
<     for (i = 0; i < 100; i++)
---
>     for (i = 0; i < 100; ++i)

我们将编译它们,并获得生成的汇编器:

$ gcc -c i++.c ++i.c
$ gcc -S i++.c ++i.c

我们可以看到生成的对象和汇编程序文件都是相同的。

$ md5 i++.s ++i.s
MD5 (i++.s) = 90f620dda862cd0205cd5db1f2c8c06e
MD5 (++i.s) = 90f620dda862cd0205cd5db1f2c8c06e

$ md5 *.o
MD5 (++i.o) = dd3ef1408d3a9e4287facccec53f7d22
MD5 (i++.o) = dd3ef1408d3a9e4287facccec53f7d22

其他回答

@Mark 即使编译器允许优化(基于堆栈的)变量的临时副本,并且gcc(在最近的版本中)正在这样做, 这并不意味着所有编译器都会这样做。

我刚刚用我们在当前项目中使用的编译器测试了它,4个中有3个没有优化它。

永远不要假设编译器是正确的,特别是如果可能更快,但永远不会更慢的代码很容易阅读。

如果你的代码中没有一个操作符的愚蠢实现:

我喜欢++i胜过i++。

请不要让“哪个更快”的问题成为使用哪个的决定因素。你可能永远不会关心那么多,此外,程序员的阅读时间比机器的时间要昂贵得多。

使用任何对阅读代码的人最有意义的方法。

执行摘要:没有。

i++可能比++ I慢,因为I的旧值 可能需要保存以备以后使用,但实际上都是现代的 编译器将对其进行优化。

我们可以通过查看这个函数的代码来证明这一点, 都是++i和i++。

$ cat i++.c
extern void g(int i);
void f()
{
    int i;

    for (i = 0; i < 100; i++)
        g(i);

}

文件是一样的,除了++i和i++:

$ diff i++.c ++i.c
6c6
<     for (i = 0; i < 100; i++)
---
>     for (i = 0; i < 100; ++i)

我们将编译它们,并获得生成的汇编器:

$ gcc -c i++.c ++i.c
$ gcc -S i++.c ++i.c

我们可以看到生成的对象和汇编程序文件都是相同的。

$ md5 i++.s ++i.s
MD5 (i++.s) = 90f620dda862cd0205cd5db1f2c8c06e
MD5 (++i.s) = 90f620dda862cd0205cd5db1f2c8c06e

$ md5 *.o
MD5 (++i.o) = dd3ef1408d3a9e4287facccec53f7d22
MD5 (i++.o) = dd3ef1408d3a9e4287facccec53f7d22

我总是喜欢预增量,然而……

我想指出的是,即使在调用运算符++函数的情况下,如果函数得到内联,编译器将能够优化掉临时函数。由于操作符++通常很短,并且经常在头文件中实现,因此它很可能被内联。

因此,出于实际目的,这两种形式的性能之间可能没有太大差异。然而,我总是喜欢预增量,因为它似乎更好地直接表达我想说的,而不是依赖于优化器来解决它。

此外,给优化器更少的任务可能意味着编译器运行得更快。

我的C有点生疏了,所以我提前道歉。就速度而言,我可以理解结果。但是,我对这两个文件是如何得到相同的MD5哈希感到困惑。也许for循环也可以运行,但是下面两行代码不会生成不同的程序集吗?

myArray[i++] = "hello";

vs

myArray[++i] = "hello";

第一个函数将值写入数组,然后将i加1,第二个函数将i加1,然后将值写入数组。我不是汇编专家,但我只是不明白这两行不同的代码如何生成相同的可执行文件。

这只是我的个人意见。