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
cbsw
V2EX  ›  Python

Pypy速度超快啊

  •  
  •   cbsw ·
    dengshuan · 2013-11-28 15:12:58 +08:00 · 9355 次点击
    这是一个创建于 4011 天前的主题,其中的信息可能已经有所发展或是发生改变。
    同样一段程序,C用10s,Pypy需要10.2s,Python需要218.3s。
    最近用Python写了个数值计算程序,实在无法忍受龟速,改用Pypy作解释器后发现速度与C编译出来的不相上下,JIT技术实在太NB了
    18 条回复    1970-01-01 08:00:00 +08:00
    initialdp
        1
    initialdp  
       2013-11-28 15:14:28 +08:00
    请问在哪个系统下?windows还是linux?谢谢。

    我也想研究一下pypy,据说是python的未来。
    cbsw
        2
    cbsw  
    OP
       2013-11-28 15:21:46 +08:00
    @initialdp Linux平台,Fedora19
    duzhe0
        3
    duzhe0  
       2013-11-28 15:24:36 +08:00
    是不是c代码实现的不够高效?把代码贴出来看一下
    cbsw
        4
    cbsw  
    OP
       2013-11-28 15:58:51 +08:00   ❤️ 1
    Simpson和梯形公式计算积分
    /* C version */
    float f(float x){
    return sqrt(x)*log(x);
    }
    while (N < 100000){ /* Simpson integration*/
    h = (b-a)/N;
    Sn = h*f(b)/6;
    for (int i = 0; i < N; i++){
    if (i == N-1)
    Sn += h/6 * (4*f(a+(i+1.0/2)*h));
    else
    Sn += h/6 * (4*f(a+(i+1.0/2)*h) + 2*f(a+(i+1.0)*h));
    }
    errS = fabs(Sn-rval);
    N += 100;
    /* fprintf (fp,"%d\t%.9f\n",N,errS); */
    }
    N=1000;
    while (N<100000){ /* Trapezoidal integration */
    h = (b-a)/N;
    Tn = 0.0;
    for (int i = 0; i < N; ++i) {
    if (i!=0)
    Tn += h/2 * (f(a+i*h) + f(a+(i+1)*h));
    }
    errT = fabs(Tn-rval)
    N += 100;
    /* fprintf(fp,"%d\t%.9f\n",N,errT); */
    }
    这个程序是用来确定舍入误差开始超过积分方法误差时的积分步长,当然这个程序实际中没有多大意义
    # python version
    for N in n:
    h = (b-a)/N
    # Sn
    Sn = h*f(b)/6
    for k in range(0,N,1):
    if k==N-1:
    Sn += h/6 * (4*f(a+(k+1.0/2)*h))
    else:
    Sn += h/6 * (4*f(a+(k+1.0/2)*h) + 2*f(a+(k+1)*h))
    # Tn
    Tn = 0.0
    for k in range(0,N,1):
    if k!=0:
    Tn += h/2 * (f(a+k*h) + f(a+(k+1)*h))
    errS.append(abs(Sn-real))
    errT.append(abs(Tn-real))
    当然这个程序可以优化,但相同的算法,用不同语言、解释器实现,这样比较应该还算比较公平
    thwawar
        5
    thwawar  
       2013-11-28 16:52:07 +08:00   ❤️ 1
    @cbsw 点错了居然给了你个感谢。。。我其实想说的是: 你能把代码贴 gist.github.com 否?
    ChiangDi
        6
    ChiangDi  
       2013-11-28 18:42:09 +08:00 via Android
    据说pypy的目标是速度超越C
    cbsw
        7
    cbsw  
    OP
       2013-11-28 20:58:44 +08:00
    @thwawar 像V2EX这样的网站,我觉得应该加上代码高亮功能的。贴到 https://gist.github.com/dengshuan/7691247 上,大家可以在自己机子上测试一下,我在Fedora 19 x86_64平台测试的
    cbsw
        8
    cbsw  
    OP
       2013-11-28 21:01:18 +08:00
    好吧,V2EX居然直接把 gist 上的代码抓过来了,还高亮显示了
    duzhe0
        9
    duzhe0  
       2013-11-28 21:15:31 +08:00
    这个代码的主要开销应该在sqrt和log上, pypy能把性能优化到和C一个水平应该很正常。如果有较多内存分配和释放的操作就比较难了。
    cbsw
        10
    cbsw  
    OP
       2013-11-28 21:21:10 +08:00
    @duzhe0 其实我今天才用Pypy,对于其技术实现还很不清楚,它的优化主要是JIT技术吗?另外据说会把编译缓存下来,这个编译出来的东西是放在哪儿的?
    ivenvd
        11
    ivenvd  
       2013-11-28 22:14:44 +08:00
    @cbsw 放在内存里,下次执行这些语句的时候,直接执行编译后的二进制。
    ivenvd
        12
    ivenvd  
       2013-11-28 22:20:47 +08:00
    @cbsw C 语言的速度跟编译器和编译选项很有关系的。你这段代码如果编译器足够智能的话,可以把所有计算相关的逻辑都删掉,因为计算结果没有被用到……一般 gcc 会加上 -O2,才算实际应用中的性能……另外 march 等选项还可以作 CPU 特定的优化,这些 pypy 可能都达不到……
    likuku
        13
    likuku  
       2013-11-29 00:44:03 +08:00
    @ivenvd 如今的机器们…-O2,march …加与不加,差距真的人类可感知么?
    VYSE
        14
    VYSE  
       2013-11-29 01:48:11 +08:00
    好吧楼主,我在WINDOWS机器上用VC无优化编的跑了7.4秒,O1优化3秒(O2就没跑)
    MINGW加O2得12.167,奇怪的是LINUX GCC O2也得7.78

    用ICC估计你的代码没有PRINT,直接跑了0秒,然后把你注释掉的写文件开启成PRINT后,结果是:
    99000 0.000000026
    99100 0.000000093
    99200 0.000000212
    99300 0.000000033
    99400 0.000000212
    99500 0.000000093
    99600 0.000000301
    99700 0.000000033
    99800 0.000000026
    99900 0.000000301
    100000 0.000000146
    2.845000000

    加/fast后输出到NULL后终于到2.194000000

    PYPY现在跑算法的速度快接近无优化的C了,但实际时候其他的开销还是很大。
    bububut
        15
    bububut  
       2013-11-29 07:51:00 +08:00   ❤️ 1
    确实比原来快上很多,尝试的时候感觉很爽。可惜对numpy支持的还不好,实际用起来不方便。目前要想提速还是得用Cython
    yishenggudou
        16
    yishenggudou  
       2013-11-29 09:54:18 +08:00
    @bububut cython 方向不错 自己可控度高
    ivenvd
        17
    ivenvd  
       2013-11-29 10:12:08 +08:00
    @likuku 那要看你跑的是什么程序……在有些测试上可以相差 8 倍: http://www.phoronix.com/scan.php?page=article&item=gcc_47_optimizations&num=2
    ivenvd
        18
    ivenvd  
       2013-11-29 10:14:27 +08:00
    @yishenggudou 但是除非你是汇编牛人,自己优化代码往往是赶不上机器自动优化的……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3246 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:41 · PVG 08:41 · LAX 16:41 · JFK 19:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.