C/C++培训
达内IT学院
400-996-5531
i ++ 和 ++ i,性能有区别吗?这是一个同学问的问题,据说是一个面试问题。
for(int i = 0; i < n; i ++)
和
for(int i = 0; i < n; ++ i)
两个循环,在循环变量的更新上,一个是 i ++,一个是 ++ 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) 的算法,怎么电脑没反应了?
答案是:电脑在反应,但需要相当长的时间。
当你还在担心能否就业时,达内学员提前被企业录取;当你转辗于各大招聘会时,达内学员收到了高薪offer;当你在各大招聘网站投递简历时,达内学员中有人一毕业进入五百强名企。所以选择很重要。找C++培训班,选达内就对了。
填写下面表单即可预约申请免费试听!怕钱不够?可就业挣钱后再付学费! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!
Copyright © 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有
Tedu.cn All Rights Reserved