推荐学习书目
› 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 · Apr 2, 2016 · 6532 views
    This topic created in 3871 days ago, the information mentioned may be changed or developed.

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

    倒没那么夸张, Cython 现在对 range 和 xrange 有优化, 会直接转成循环, 以前那种 for i from 0<=i<95550000 的方言被废了, 然后默认的编译参数又是-O2, 直接把循环这部分给优化掉了,等于什么都没做直接给 i 赋值了
    SlipStupig
    SlipStupig
    Apr 3, 2016
    18
    每次+一次就是内存申请一次啊,而且你用 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
    simon4545
    OP
    Apr 3, 2016
    19
    @est 我后面也试了,正如你所说的一样。
    能请教一下原因么?
    pynix
    pynix
    Apr 3, 2016
    20
    不可变对象,一直在申请和释放内存。
    imn1
    imn1
    Apr 3, 2016
    21
    @simon4545
    while 也比 for 快一点
    python 官方都建议用列表 /元组表达式代替 for 循环优化
    simon4545
    simon4545
    OP
    Apr 3, 2016
    22
    @imn1 python 我是新手,你说的列表元组是指的是用[sum(x ) for i in range(59990000)]推导么?
    imn1
    imn1
    Apr 3, 2016
    23
    @simon4545
    (x for x in ...)
    [x for x in ...]
    wizardforcel
    wizardforcel
    Apr 3, 2016 via Android
    24
    node 自带了 jit ,你用 xpcshell 试试。(逃
    fullpowers
    fullpowers
    Apr 3, 2016 via Android
    25
    我智商捉急,求问为什么是 95549999
    zonghua
    zonghua
    Apr 3, 2016 via iPhone
    26
    @bigtan 我想深入了解一下 cython
    MrEggNoodle
    MrEggNoodle
    Apr 3, 2016
    27
    @bigtan 看到你这个,我决定深入了解一下 cython 了。
    simon4545
    simon4545
    OP
    Apr 4, 2016
    28
    +1 cython
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1669 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 67ms · UTC 11:26 · PVG 19:26 · LAX 03:26 · JFK 06:26
    ♥ Do have faith in what you're doing.