算 1 到 10 亿的所有自然数的和,c 用时 4.4's, java 用时 3.8's,python 用时 302.9's,已吓尿,求解释

2014-10-18 16:37:36 +08:00
 MonkLuf
算1到10亿的所有自然数的和,c用时4.4's, java用时3.8's,python用时302.9's。

吓尿!!!

java居然这么快,居然比c都快!!python居然慢了将近100倍也太夸张了吧!!这个速度突然毁掉了我的世界观。。。。。

求懂java的人带详细理由的告诉我为什么java会这么快,python为何慢这么多(慢得太离谱了。。。)
13087 次点击
所在节点    问与答
106 条回复
ChanneW
2014-10-19 22:30:08 +08:00
凑热闹, 程序不变, 执行结果如下:

./plus.bin
sum: 500000000500000000, time used: 2.820283 s

python plus.py
sum : 500000000500000000 , use time : 83 s

pypy plus.py
sum : 500000000500000000 , use time : 1 s

java plus
sum :500000000500000000 , use time : 0.871000 s
ChanneW
2014-10-19 22:32:10 +08:00
pypy 的结果还是让人很欣慰的, 这些年没白搞啊. 速度差不多, 统计方法不精确.
ChanneW
2014-10-19 22:55:54 +08:00
没人看一眼 ruby 么?

ruby plus.rb
sum : 50000005000000 , use time : 0.370955077
ChanneW
2014-10-19 22:59:08 +08:00
汗, 打错了 , 吓人

ruby plus.rb
sum : 500000000500000000 , use time : 37.145211624
msg7086
2014-10-20 07:09:25 +08:00
@lushl9301 对于完全没有优化代码,你说的基本正确。
从汇编角度来说,数字存储在内存中,要加一的时候,先要从内存里mov到寄存器,然后复制一份寄存器数据,把原始寄存器里的值add常数1,然后再mov回内存,最后返回拷贝寄存器里的值。

比如
mov ecx, DWORD PTR [ESI]
mov eax, ecx
add ecx, 1 # or # inc ecx
mov DWORD PTR [ESI], ecx

但是如果加上了哪怕一点点优化,就会变成
# ecx contains variable i
inc ecx

这已经是一个数量级的优化了。
ToughGuy
2014-10-20 10:10:04 +08:00
~# time python -c 'sum(xrange(1, 1000000001))'

real 0m5.378s
user 0m5.382s
sys 0m0.000s

~# time pypy -c 'sum(xrange(1, 1000000001))'

real 0m0.873s
user 0m0.865s
sys 0m0.008s

用内建函数计算也差不到哪里去吧。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://tanronggui.xyz/t/139818

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX