python 纯加减运算慢 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
simon4545
V2EX    Python

python 纯加减运算慢

  •  
  •   simon4545 2016-04-02 14:28:46 +08:00 5796 次点击
    这是一个创建于 3528 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 接近

    28 条回复    2016-04-04 13:46:05 +08:00
    koykoi
        1
    koykoi  
       2016-04-02 15:01:29 +08:00
    这种 hot spot 代码不正是 JIT 的优势吗
    clino
        2
    clino  
       2016-04-02 15:17:23 +08:00
    nodejs 应该和 pypy 一样都用了 jit 吧?
    clino
        3
    clino  
       2016-04-02 15:26:31 +08:00
    我这里的结果是
    -在循环里算两个+-耗时 15.1 秒
    -在循环里算一个+耗时 9.89 秒
    -循环里 pass 耗时 3.72 秒
    BOYPT
        4
    BOYPT  
       2016-04-02 15:27:47 +08:00
    大概是因为 python 里面的整数是 immutable 的对象,你这样的操作就是重复生成对象和回收对象,所以效率较低;大概使用 numbers 模块里面功能会有改善。
    josephok
        5
    josephok  
       2016-04-02 16:01:50 +08:00
    用 python3 试试
    ikw
        6
    ikw  
       2016-04-02 16:09:22 +08:00
    本来就应该是 9554999 的吧?
    python3 是:
    95549999
    10.84103798866272
    Zzzzzzzzz
        7
    Zzzzzzzzz  
       2016-04-02 16:09:46 +08:00
    光这个 xrange 就得两三秒.
    要改进性能的话把这段代码抽出来上 Cython , i = 0 前面加 cdef long, 秒变毫秒级.
    simon4545
        8
    simon4545  
    OP
       2016-04-02 16:18:36 +08:00
    python3 执行也是一样的,而且还要更久一点
    有没有 jit 居然相差那么大
    realpg
        9
    realpg  
    PRO
       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";
    slixurd
        10
    slixurd  
       2016-04-02 19:21:49 +08:00
    居然连 microbench 之类的工具都没用,在这裸写。。。。
    bigtan
        11
    bigtan  
       2016-04-02 19:24:52 +08:00   2
    用 Python ,执行效率一般难以成为瓶颈,因为,他可以通过别的优化手段轻松的达到 C-level 的执行效率。
    theoractice
        12
    theoractice  
       2016-04-02 20:27:43 +08:00
    @bigtan 42.7ns ?表示震惊
    zhuangzhuang1988
        13
    zhuangzhuang1988  
       2016-04-02 22:01:59 +08:00
    没 jit 就得这么慢, 虽然里面有一些 intern 缓存优化。但是对这些纯计算的没啥鸟用。。
    bigtan
        14
    bigtan  
       2016-04-02 22:04:09 +08:00
    @theoractice 有缓存的可能,你可以看 best case 。 42.7ns*24.87=1061.9ns ,不过也足够惊人的了。
    est
        15
    est  
       2016-04-02 22:21:06 +08:00
    其实 python 加减乘除不慢, for 比较慢。
    mathgl
        16
    mathgl  
       2016-04-02 22:30:28 +08:00
    这种代码, jit 稍微优化一下就是常数了。
    Zzzzzzzzz
        17
    Zzzzzzzzz  
       2016-04-02 22:37:08 +08:00
    @theoractice
    @bigtan

    倒没那么夸张, Cython 现在对 range 和 xrange 有优化, 会直接转成循环, 以前那种 for i from 0<=i<95550000 的方言被废了, 然后默认的编译参数又是-O2, 直接把循环这部分给优化掉了,等于什么都没做直接给 i 赋值了
    SlipStupig
        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}
    simon4545
        19
    simon4545  
    OP
       2016-04-03 02:47:55 +08:00
    @est 我后面也试了,正如你所说的一样。
    能请教一下原因么?
    pynix
        20
    pynix  
       2016-04-03 04:27:50 +08:00
    不可变对象,一直在申请和释放内存。
    imn1
        21
    imn1  
       2016-04-03 10:44:45 +08:00
    @simon4545
    while 也比 for 快一点
    python 官方都建议用列表 /元组表达式代替 for 循环优化
    simon4545
        22
    simon4545  
    OP
       2016-04-03 11:40:57 +08:00
    @imn1 python 我是新手,你说的列表元组是指的是用[sum(x ) for i in range(59990000)]推导么?
    imn1
        23
    imn1  
       2016-04-03 12:37:03 +08:00
    @simon4545
    (x for x in ...)
    [x for x in ...]
    wizardforcel
        24
    wizardforcel  
       2016-04-03 12:55:30 +08:00 via Android
    node 自带了 jit ,你用 xpcshell 试试。(逃
    fullpowers
        25
    fullpowers  
       2016-04-03 14:23:34 +08:00 via Android
    我智商捉急,求问为什么是 95549999
    zonghua
        26
    zonghua  
       2016-04-03 14:54:23 +08:00 via iPhone
    @bigtan 我想深入了解一下 cython
    MrEggNoodle
        27
    MrEggNoodle  
       2016-04-03 15:54:51 +08:00
    @bigtan 看到你这个,我决定深入了解一下 cython 了。
    simon4545
        28
    simon4545  
    OP
       2016-04-04 13:46:05 +08:00
    +1 cython
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2681 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 08:08 PVG 16:08 LAX 00:08 JFK 03:08
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86