刚才测试了一下 Node.js 与 python 的计算性能,震惊了

2014-05-23 10:10:25 +08:00
 codingpp
测试脚本之一,是计算40位的斐波那契数列,测试脚本如下:
node.js
function fibo (n) {
return n > 1 ? fibo(n - 1) + fibo(n - 2) : 1;
}
console.log(fibo(40));

python
def fibo(n):
return fibo(n - 1) + fibo(n - 2) if n > 1 else 1
print fibo(40)

php
<?php
function fibo($n){
if($n > 1) {
return fibo($n - 1) + fibo($n - 2);
} else {
return 1;
}
}
echo fibo(40);

测试结果如下:

node.js
real 0m3.329s
user 0m3.318s
sys 0m0.010s

python
real 1m11.325s
user 1m11.259s
sys 0m0.015s

php
real 1m26.551s
user 1m26.448s
sys 0m0.027s


node.js居然比python快了23倍之多

之后我又写了一个测试脚本,就是简单的循环
i = 0
t = 1
while(i < 50000000):
t = t + i
i += 1
print t

node.js居然比python快了70多倍。。比php快了16倍,c语言也比node.js慢了一点点

虽然也知道python慢,但是这个差的有点多啊
58400 次点击
所在节点    Python
105 条回复
yueyoum
2014-05-23 12:01:23 +08:00
@codingpp

确实 递归很慢。
我并不是说递归不好,

而是 递归在 python 中很危险

1, 大量函数调用, 性能杀手
2, python没有尾递归优化,一点递归调用就会消耗大量的栈空间
3, 因为第2点,所以python有递归层数限制。超过这个限制,程序就会崩溃

所以,除非是少量的,你确定不会崩溃的, 否则别在python中用递归。


LZ 如果喜欢 递归,
看看 erlang, 用递归解决一切问题。
非常优雅。
binux
2014-05-23 12:04:47 +08:00
@codingpp 来,你说说看优化,递归消耗,动态类型对性能影响占比各是多少?你为什么选择这个比例。
jiang42
2014-05-23 12:06:32 +08:00
@yueyoum 不是应该我大 Haskell 嘛!
jiang42
2014-05-23 12:08:11 +08:00
@yueyoum Python 创始人说递归不是一个好程序员的必备,所以没有尾递归优化,真是蛋疼
codingpp
2014-05-23 12:19:59 +08:00
@binux
我觉得动态类型对性能的影响不会很大

造成实验结果有这样的误差,本质上应该就是算法优化上的问题,而我觉得有必要了解一下是如何优化的

还有循环性能差这么多,这个是个比较重要的问题啊
jamiesun
2014-05-23 12:26:06 +08:00
@codingpp python科学计算有自己的模块和加速方案,也不是这么玩的.
jsonline
2014-05-23 12:31:08 +08:00
@jiang42 没打着……我说的是程序员自己优化
yueyoum
2014-05-23 12:42:29 +08:00
@jiang42

急着去厕所 ,看看erlang的 递归和 模式匹配吧, 这才是优雅的程序啊。

https://gist.github.com/yueyoum/d624d7358a23304b02da
jsonline
2014-05-23 12:45:19 +08:00
@yueyoum 优雅见仁见智,但是说实话没有 Python 易懂。另外为何命名不用全称要用缩写。 Num 为什么不是 Number。
davidjqq19
2014-05-23 12:48:19 +08:00
C语言:
unsigned int fibo(unsigned int n)
{
return n>1 ? fibo(n-1) + fibo(n-2) : 1;
}

int main()
{
printf("%u.\n", fibo(40));
return 0;
}

[*root*@/work/bash 12:47:45] : time ./a.out
165580141.

real 0m0.844s
user 0m0.839s
sys 0m0.000s
binux
2014-05-23 12:53:33 +08:00
@codingpp 那你说说这里面都有何种优化,影响是多少,实际中这种优化有多少效果
Monad
2014-05-23 12:53:50 +08:00
@jsonline 窃以为num已经可以代表number之意
就好比我在这发个dns大家都知道是啥
CMGS
2014-05-23 12:57:32 +08:00
我先占个坑……

1.
vob636
2014-05-23 12:57:45 +08:00
话说你这种不公平的比较有什么意义么?node明显是有优化过程,而python以及php是基本上没有,你怎么就不用python里面的yield?而且node非阻塞原型……python都有实现……你就凭借这个fab函数,比较语言速度也没有这么比较的吧
NemoAlex
2014-05-23 12:59:16 +08:00
这种测试基本就是在比赛谁打 log 更快啊,有意义么?
CMGS
2014-05-23 13:02:04 +08:00
草,手机就是不好回复……

1. 你拿一个带jit的跟解释op code的比运算大丈夫?
2. python有个很magic的尾递归优化,裸cpython就算了
3. pypy预热足够的情况下……呵呵
4. 说白了时间换空间有什么好比的……
lm902
2014-05-23 13:05:22 +08:00
换成IronPython 试试
yueyoum
2014-05-23 13:08:19 +08:00
@jsonline

恩, 我对递归更习惯一点。
当时用 c++ 写一个 解数独程序, 递归很好写, 但是递归层数多了, 会 core dump。
最后还是花了点时间 改成循环。


我不是计算机专业的, 刚开始写C代码的时候,就写了很多递归。感觉很自然。
但我计算机专业的同学,当年交流的时候,他表示递归很难理解……
anchoretic
2014-05-23 13:17:15 +08:00
牛~
sandtears
2014-05-23 13:27:44 +08:00
python 跑斐波那契确实很慢,不过可以用 Ctypes 优化

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

https://www.v2ex.com/t/113887

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

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

© 2021 V2EX