美文网首页
【C/C++编程学习笔记】i ++ 和 ++ i,性能有区别吗?

【C/C++编程学习笔记】i ++ 和 ++ i,性能有区别吗?

作者: 折扇戏美人_a48e | 来源:发表于2020-05-28 14:30 被阅读0次

    这是一个同学问的问题,据说是一个面试问题。

    for(inti =0; i < n; i ++)

    for(inti =0; i < n; ++ i)

    两个循环,在循环变量的更新上,一个是 i ++,一个是 ++ i。

    性能有区别吗?


    首先,我要说,我不是很赞同这类“谭浩强式的问题”。在我看来,对这类问题如数家珍,和编程能力一点儿关系都没有。

    但是,对于一个对计算机感兴趣的孩纸,时不时地研究一下这类“犄角旮旯”的问题,还是一件很有意思的事情。

    对于 i ++ 和 ++ i 在语法上的区别,相信大家都了解。

    i ++ 是先取值,后 ++。

    如果 i = 0,则 int a = i ++ 以后,a 为 0,i 为 1。

    而 ++ i 是先 ++,后取值。

    如果 i = 0,则 int a = ++ i 以后,a 为 1,i 为 1。

    如果我们将 i ++ 和 ++ i 想成是两个函数,可以这样理解。

    i ++ 要先暂存 i 的初值,然后对 i 进行加 1 操作,之后返回之前暂存的 i 的初值。伪码如下:

    int j = i;

    i= i +1;

    return j;

    而 ++ i,则不需要暂存 i 的初值,直接对 i 进行加 1 操作以后,返回新的 i 的值就好了。

    i = i + 1;

    return i;

    这样看,相信大家就能一目了然了,i ++ 的过程由于需要暂存 i 的初值,所以,理论上,性能耗费会更高一些。

    因此,如果大家看一些“上古”的程序设计书籍(以 C 语言为主),会提及,上面的 for 循环,用 ++ i 更好。


    但是,在现代编程环境中,这一点性能偏差,完全可以忽略不计。

    一方面,现代编译器的优化,使得编译器完全可以分析出,在上述 for 循环的 i ++ 以后,对 i 的结果并没有进行赋值使用。从而,编译器会进行优化,最后编译出的逻辑,不进行上面所说的无用的暂存。

    另一方面,即使使用不优化的编译,有人统计过,对于现代计算机来说,循环次数要多达 10^47 次,才可以产生人类可以察觉的性能差异。

    10^47 是什么概念?

    整型可以存储的数字规模是 10^9 这个量级。同学们可以在自己的计算机上尝试一下,做一个循环 10^9 次的循环。每一次只是给一个整型赋值,看走完这个循环,需要多少时间?

    以 C++ 为例,大概就是这样的一个程序:

    对于大多数同学的计算机,相信这个循环需要的时间,是高于 1 秒钟的。在我的计算机上,需要大概 1.3 秒。

    就算只需要 1 秒钟,10^47 是 10^9 的 10^38 倍。也就是,循环 10^47 次,大概需要 10^38 秒。

    这是什么概念呢?同学们可以用计算机计算一下,10^38 秒大概是 3*10^30 这么多年。

    因为一天不过 60 * 60 * 24 =86400 秒;

    一年不过 86400 * 365 = 3.1536 * 10^7 秒。

    我查了一下,太阳系大概诞生于 64 亿年前,即 6.4 * 10^9 年前。这么算,现代计算机循环 10^47 这么多操作的时间,亿亿个太阳系已经诞生了。

    是亿亿,不是一亿。用 3*10^30 除以 6.4*10^9,得到的结果,比一亿个一亿,还要大五万倍左右。

    所以,在通常使用的时候,i ++ 和 ++ i 的这个性能差距,如果在一些语言或者编译环境(解析环境)中真的存在,也完全可以忽略不计。


    那么,在逻辑等价的情况下,应该使用 i ++ 还是 ++ i ?

    在这种情况下,应该考虑的就是表意性。即哪种写法最好理解?

    可惜,表意性是一个主观的事情,没有客观标准。因此,公说公有理,婆说婆有理。

    或许这也就是为什么,在很多新兴语言中,干脆直接废除掉 i ++ 或者 ++ i 这种语法吧。

    i = i + 1,多清晰:)

    写完这篇小文,发现文中的计算,对于大家对数量级有一个直观的理解很有帮助。

    很多同学曾经问我类似这样的问题:一个 O(n) 的算法,一秒钟就跑完了,换成 O(n^2) 的算法,怎么电脑没反应了?

    答案是:电脑在反应,但需要相当长的时间。

    假设你的 n 是 10 万左右。如果 O(n) 的算法用 1 秒钟,O(n^2) 的算法就要用大概 10 万秒钟。(不严格,因为 0.5n^2 也叫 O(n^2))

    10 万秒钟,就是要一天多的时间。因为,上文计算了,一天不过 86400 秒,即 8 万多秒。所以,要真想看到 O(n^2) 算法的计算结果,耐心等着就好。

    如果不想等这一天多的时间...... 那就是学习算法的意义了!


    如果你想跟着小编一起学编程的话!

    可以来我的C语言/C++编程学习交流俱乐部,【点击进入】

    还有(源码,零基础教程,项目实战教学视频),欢迎初学者和正在进阶中的小伙伴们! 

    相关文章

      网友评论

          本文标题:【C/C++编程学习笔记】i ++ 和 ++ i,性能有区别吗?

          本文链接:https://www.haomeiwen.com/subject/scnyahtx.html