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

为什么 Py3k 要比 Py 2 慢?

  •  
  •   Feiox ·
    feiox · 2015-05-12 15:27:23 +08:00 · 5117 次点击
    这是一个创建于 3273 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如果是各种 Pythonic 的列表处理,py3k 确实有优势。但感觉函数式写法越来越多。
    但,跑各种 web 应用,却一直都会慢一些。难道是 unicode?我在 py2 中也使用了各种 unicode 啊 from __future__ import unicode_literals
    还有,你们遇到过 py3k 的哪些坑,出来聊聊呗

    45 条回复    2015-05-20 16:34:25 +08:00
    laotaitai
        1
    laotaitai  
       2015-05-12 16:23:34 +08:00
    函数式? 哈哈哈! 我笑抽了!
    lightening
        2
    lightening  
       2015-05-12 16:26:36 +08:00
    @laotaitai 函数式是一种思想,什么语言都可以用函数式写法。
    Feiox
        3
    Feiox  
    OP
       2015-05-12 17:55:51 +08:00
    @laotaitai 比如,从语言层面鼓励多使用列表、返回不可变对象、运用迭代等。都算是把。
    @lightening 最大的愿望还是能解除对 lambda 的诸多限制。
    clino
        4
    clino  
       2015-05-12 18:02:29 +08:00
    什么样的代码 3 比 2 慢?
    还没开始用3,不过想了解下
    kxxoling
        5
    kxxoling  
       2015-05-12 18:05:03 +08:00
    @Feiox 函数式。。。 (¬д¬) reduce 差点就没了的说
    caoyue
        6
    caoyue  
       2015-05-12 18:14:50 +08:00
    Python3 本来就比 Python2 慢吧
    我记得 3.0 release 的时候官方文档都写了比 2.X 慢多少来着,现在是否有改善就不知道了=-=

    另外本身不是函数式的语言大量不适当的使用「函数式风格」也会导致效率降低啊
    Feiox
        7
    Feiox  
    OP
       2015-05-12 18:21:33 +08:00
    @caoyue 除了字符串的原因,为什么会慢呢?

    @kxxoling 对呀,但也感觉 G 老爷子特别喜欢列表推导。
    zhyu
        8
    zhyu  
       2015-05-12 18:33:16 +08:00
    不如用 cProfile 看看哪里慢?
    caoyue
        9
    caoyue  
       2015-05-12 18:37:23 +08:00
    @Feiox
    水平太低,我也不知道为什么会慢=-=

    很少有推荐使用 map 、filter 来替代 list comprehensions 的吧,我记得之前 Google 的 Python Style Guide 是禁止使用 map 的
    monsabre1
        10
    monsabre1  
       2015-05-12 18:39:54 +08:00
    @lightening

    乱讲 你用java写个全函数式编程
    neoblackcap
        11
    neoblackcap  
       2015-05-12 19:07:21 +08:00
    Py3k刚开始是慢,至少3.1, 3.2这些是会比2.7慢的,然后3.4就开始慢慢上来了。至于为什么慢?好像是跟新式类的实现有关的,没错就是那个object
    BOYPT
        12
    BOYPT  
       2015-05-12 19:09:58 +08:00
    不是吧,不用map filter写python还有啥意义。
    kxxoling
        13
    kxxoling  
       2015-05-12 19:19:37 +08:00 via iPhone
    @BOYPT map 和 filter 不受影响,只有 reduce 差点被砍了,不过开发者的反对挺强烈的。
    whatisnew
        14
    whatisnew  
       2015-05-12 19:20:44 +08:00 via iPhone
    @lightening 你用 java 写一个试试
    lightening
        15
    lightening  
       2015-05-12 19:55:47 +08:00
    @monsabre1
    @whatisnew

    不要改写任何变量,用函数调用代替变量赋值,用递归替代循环。全函数不可能(比如和外部系统交互),但是大量应用函数编程思想完全没问题。
    phx13ye
        16
    phx13ye  
       2015-05-12 20:18:42 +08:00
    不知道有啥好笑的,oop就不能fp?


    Functional programming in non-functional languages

    It is possible to use a functional style of programming in languages that are not traditionally considered functional languages.[42] For example, both D and Fortran 95 explicitly support pure functions.[43]

    First-class functions have slowly been added to mainstream languages. For example, in early 1994, support for lambda, filter, map, and reduce was added to Python. Then during the development of Python 3000, Guido van Rossum called for the removal of these features.[44] However, he later changed his mind, and only reduce was removed,[45] though it remains accessible via the functools standard library module.[46] First-class functions were also introduced in PHP 5.3, Visual Basic 9, C# 3.0, and C++11[citation needed].

    In Java, anonymous classes can sometimes be used to simulate closures;[47] however, anonymous classes are not always proper replacements to closures because they have more limited capabilities.[48] Java 8 supports lambda expressions as a replacement for some anonymous classes.

    摘自维基百科
    monsabre1
        17
    monsabre1  
       2015-05-12 20:49:24 +08:00
    @lightening

    全函数才能热更新
    这是erlang用在电信的一个原因
    yakczh
        18
    yakczh  
       2015-05-12 20:51:05 +08:00
    那是不是象php一样,改了代码就能立马生效了?
    lightening
        19
    lightening  
       2015-05-12 20:51:46 +08:00
    @monsabre1 函数编程又不是只有热更新一个目的
    monsabre1
        20
    monsabre1  
       2015-05-12 20:53:27 +08:00
    @phx13ye

    c++ python都是多范式
    java即便模拟也是伪的 也会很丑陋

    java是标准oo helloworld也要写类
    多范式想彻底函数型 必须先有过程型
    话说java能过程型写个helloworld吗
    monsabre1
        21
    monsabre1  
       2015-05-12 20:54:24 +08:00
    @lightening

    热更新是函数型最主要那个目的
    monsabre1
        22
    monsabre1  
       2015-05-12 20:55:37 +08:00
    @yakczh

    erlang无需停机 你见过听过电信定期停机更新吗
    lightening
        23
    lightening  
       2015-05-12 21:01:41 +08:00
    @monsabre1 Maybe. 但也可以用来提升代码可读性、惰性求值、方便并发。
    laike9m
        24
    laike9m  
       2015-05-12 22:02:34 +08:00
    测试代码呢?
    monsabre1
        25
    monsabre1  
       2015-05-12 22:30:02 +08:00
    @lightening

    并发也是优点(不过nodejs即便oo 并发也不错)
    熟手开发效率高也是
    可读性保留 特别是人员混杂的时候

    好在python是脚本 多操纵引擎
    FP OO 都没问题 都可以轻松控制住局面
    kaneg
        26
    kaneg  
       2015-05-12 22:30:18 +08:00
    可能3主要是在语言层面增加了不少新功能, 2已经很稳定,所以在性能上不断优化的结果。
    bdnet
        27
    bdnet  
       2015-05-12 23:48:18 +08:00 via iPhone
    3为什么就没用起来
    monsabre1
        28
    monsabre1  
       2015-05-12 23:57:04 +08:00
    python函数式如果不用map reduce filter
    完全自己改写oo到fp
    速度慢很多

    别的语言估计一样 强扭的瓜不甜
    monsabre1
        30
    monsabre1  
       2015-05-13 00:09:02 +08:00
    ```python
    import datetime

    def add(x): return x*100 + 1


    def count(x): return x + 1
    def f1(a,b):
    if b==99:
    return a
    else:
    return f1(add(a),count(b))


    def f2():
    a=0
    for x in xrange(1,100):
    a=a*100+1
    return a

    def main():
    starttime = datetime.datetime.now()
    print f1(1,1) #fp
    endtime = datetime.datetime.now()
    print (endtime - starttime).microseconds

    starttime = datetime.datetime.now()
    print f2() #oo
    endtime = datetime.datetime.now()
    print (endtime - starttime).microseconds

    if __name__=='__main__':
    main()
    ```
    输出

    ```
    10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101
    1485
    10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101
    116
    ```
    monsabre1
        31
    monsabre1  
       2015-05-13 00:24:36 +08:00
    看不出 如果语言如果不原生支持 自己非要改写

    def add(x): return x*100 + 1
    def count(x): return x + 1
    def f1(a,b):
    if b==99:
    return a
    else:
    return f1(add(a),count(b))

    这一坨比

    def f2():
    a=0
    for x in xrange(1,100):
    a=a*100+1
    return a

    有何优势 可读性也不强
    monsabre1
        32
    monsabre1  
       2015-05-13 01:20:49 +08:00
    试试胜于雄辩
    哪位改写
    def f2():
    a=0
    for x in xrange(1,100):
    a=a*100+1
    return a

    到易读简洁的functional programming

    别用map reduce filter lamda啊
    Feiox
        33
    Feiox  
    OP
       2015-05-13 03:37:46 +08:00 via Android
    ,似乎歪楼了。。。。。为什么3比2满啊
    livelazily
        34
    livelazily  
       2015-05-13 07:52:27 +08:00
    @Feiox http://stackoverflow.com/q/23453133/902058 这里有一个解释
    其实 Google 搜下 python 3 slower than python 2 就有很多答案了
    publicID001
        35
    publicID001  
       2015-05-13 08:12:53 +08:00 via Android
    @monsabre1 发代码请用gist
    imn1
        36
    imn1  
       2015-05-13 10:32:24 +08:00
    @monsabre1
    另类一下
    bin(sum(1 << (x << 1) for x in range(99))).lstrip('0b')
    monsabre1
        37
    monsabre1  
       2015-05-13 11:01:17 +08:00
    monsabre1
        38
    monsabre1  
       2015-05-13 11:02:14 +08:00
    10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101
    908
    10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101
    67
    10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101
    69
    imn1
        39
    imn1  
       2015-05-13 11:12:07 +08:00
    @monsabre1
    也就这个恰巧 10101... 可以这样写,其他问题估计就要另想了

    ps
    你用py2,要改写xrange,我在py3写的,所以直接用了range,不过应该还是比 f2(纯数字计算) 略慢
    f1用递归肯定慢,应该想办法写成装饰器/yield,不过懒得搞了
    monsabre1
        40
    monsabre1  
       2015-05-13 11:38:45 +08:00
    @imn1

    我意思是如果语言不原生支持函数型
    有人如果强行写 比较吃力 性能不好 可读性也很差

    说是卖弄技巧也不为过
    imn1
        41
    imn1  
       2015-05-13 11:43:43 +08:00
    @monsabre1
    Y,这点同意
    不过歪楼够多了,中止这个讨论吧
    monsabre1
        42
    monsabre1  
       2015-05-13 12:11:17 +08:00
    @imn1

    python3比python2慢主要是long取代了int

    函数型不是问题所在

    但函数式是一种思想,什么语言都可以用函数式写法。

    这说法也容易误导人
    Feiox
        43
    Feiox  
    OP
       2015-05-13 19:35:04 +08:00
    @livelazily 我在 Google 搜到了很多解释。我这里是想听听大家的意见。
    Feiox
        44
    Feiox  
    OP
       2015-05-13 19:40:07 +08:00
    @monsabre1 对。虽然我喜欢函数范式,但在几万十几万行多人协作、业务逻辑多余算法的代码中完全使用函数式,我总感觉一般人驾驭不了。但核心算法用函数式写确实够漂亮。
    另外,开发中不一定非 oo 即 函数,Python 的列表推导、lambda、map 等写法 都是可以写出简洁健壮的代码。
    slideclick
        45
    slideclick  
       2015-05-20 16:34:25 +08:00
    python3的列表推导主要是节省内存吧。unicode估计是个原因,ascII码不再是一个byte.另:Python 的列表推导真心比map/filter好看。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1091 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 18:20 · PVG 02:20 · LAX 11:20 · JFK 14:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.