Python 代码: import time a=time.time() i=0 for i in xrange(95550000): i +=100 i -=100 print i print time.time()-a
运行结果: 95549999 15.253000021
得到的不是 95550000 编译成了 Pyc 也一样的结果
但换成 Node.js 会快 100 倍都不止 var a=new Date(); var i; for(i = 0; i < 95550000; ++i) { i += 100; i -= 100; } console.log(i) console.log((new Date())-a)
结果: 95549999 0.21799993515
我试了 pypy,性能和 node.js 接近
1
koykoi 2016-04-02 15:01:29 +08:00
这种 hot spot 代码不正是 JIT 的优势吗
|
2
clino 2016-04-02 15:17:23 +08:00
nodejs 应该和 pypy 一样都用了 jit 吧?
|
3
clino 2016-04-02 15:26:31 +08:00
我这里的结果是
-在循环里算两个+-耗时 15.1 秒 -在循环里算一个+耗时 9.89 秒 -循环里 pass 耗时 3.72 秒 |
4
BOYPT 2016-04-02 15:27:47 +08:00
大概是因为 python 里面的整数是 immutable 的对象,你这样的操作就是重复生成对象和回收对象,所以效率较低;大概使用 numbers 模块里面功能会有改善。
|
5
josephok 2016-04-02 16:01:50 +08:00
用 python3 试试
|
6
zwpaper 2016-04-02 16:09:22 +08:00
本来就应该是 9554999 的吧?
python3 是: 95549999 10.84103798866272 |
7
Zzzzzzzzz 2016-04-02 16:09:46 +08:00
光这个 xrange 就得两三秒.
要改进性能的话把这段代码抽出来上 Cython , i = 0 前面加 cdef long, 秒变毫秒级. |
8
simon4545 OP python3 执行也是一样的,而且还要更久一点
有没有 jit 居然相差那么大 |
9
realpg 2016-04-02 19:15:31 +08:00 1
1. python 内 xrange(3)的结果是 0,1,2
2. 这种场景就是 JIT 的性能强悍啊 realpg@TestingServer17:/tmp/demo$ python python.py 95549999 15.7798058987 realpg@TestingServer17:/tmp/demo$ pypy python.py 95549999 0.574637174606 realpg@TestingServer17:/tmp/demo$ /usr/local/php5/bin/php php.php 95550000 7.9244079589844 realpg@TestingServer17:/tmp/demo$ /usr/local/php7/bin/php php.php 95550000 3.8246450424194 python2.7 python.py 代码同楼主 php.php 代码 <?php $time_start = microtime(true); for ($i=0;$i<95550000;$i++) { $i+=100; $i-=100; } $time_end = microtime(true); $time = $time_end - $time_start; echo "{$i}\n{$time}\n"; |
10
slixurd 2016-04-02 19:21:49 +08:00
居然连 microbench 之类的工具都没用,在这裸写。。。。
|
11
bigtan 2016-04-02 19:24:52 +08:00 2
用 Python ,执行效率一般难以成为瓶颈,因为,他可以通过别的优化手段轻松的达到 C-level 的执行效率。
|
12
theoractice 2016-04-02 20:27:43 +08:00
@bigtan 42.7ns ?表示震惊
|
13
zhuangzhuang1988 2016-04-02 22:01:59 +08:00
没 jit 就得这么慢, 虽然里面有一些 intern 缓存优化。但是对这些纯计算的没啥鸟用。。
|
14
bigtan 2016-04-02 22:04:09 +08:00
@theoractice 有缓存的可能,你可以看 best case 。 42.7ns*24.87=1061.9ns ,不过也足够惊人的了。
|
15
est 2016-04-02 22:21:06 +08:00
其实 python 加减乘除不慢, for 比较慢。
|
16
mathgl 2016-04-02 22:30:28 +08:00
这种代码, jit 稍微优化一下就是常数了。
|
17
Zzzzzzzzz 2016-04-02 22:37:08 +08:00
@theoractice
@bigtan 倒没那么夸张, Cython 现在对 range 和 xrange 有优化, 会直接转成循环, 以前那种 for i from 0<=i<95550000 的方言被废了, 然后默认的编译参数又是-O2, 直接把循环这部分给优化掉了,等于什么都没做直接给 i 赋值了 |
18
SlipStupig 2016-04-03 01:35:18 +08:00
每次+一次就是内存申请一次啊,而且你用 for 就变成了直接 sum 回快多了 sum(xrange(95550000)),时间明显减少太多了
3 function calls in 1.140 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 1.140 1.140 test.py:1(<module>) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 1 1.140 1.140 1.140 1.140 {sum} |
20
pynix 2016-04-03 04:27:50 +08:00
不可变对象,一直在申请和释放内存。
|
22
simon4545 OP @imn1 python 我是新手,你说的列表元组是指的是用[sum(x ) for i in range(59990000)]推导么?
|
24
wizardforcel 2016-04-03 12:55:30 +08:00 via Android
node 自带了 jit ,你用 xpcshell 试试。(逃
|
25
fullpowers 2016-04-03 14:23:34 +08:00 via Android
我智商捉急,求问为什么是 95549999
|
27
MrEggNoodle 2016-04-03 15:54:51 +08:00
@bigtan 看到你这个,我决定深入了解一下 cython 了。
|
28
simon4545 OP +1 cython
|