Cython Speed Boost与可用性

42 python performance cython

我刚遇到Cython,而我正在寻找优化Python代码的方法.我在stackoverflow,python wiki上阅读了各种帖子,并阅读了文章"优化的一般规则".

Cython是最能引起我兴趣的东西; 而不是为自己编写C代码,您可以选择在python代码本身中使用其他数据类型.

这是我试过的一个愚蠢的测试,

#!/usr/bin/python
# test.pyx
def test(value):
    for i in xrange(value):
    i**2
    if(i==1000000):
        print i

test(10000001)
Run Code Online (Sandbox Code Playgroud)

$ time python test.pyx

real    0m16.774s 
user    0m16.745s
sys     0m0.024s
Run Code Online (Sandbox Code Playgroud)

$ time cython test.pyx

real    0m0.513s 
user    0m0.196s 
sys     0m0.052s
Run Code Online (Sandbox Code Playgroud)

现在,老实说,我傻眼了.我在这里使用的代码是纯python代码,我所有改变的是解释器.在这种情况下,如果cython这样好,那么为什么人们仍然使用传统的Python解释器呢?Cython有任何可靠性问题吗?

Jus*_*eel 53

其他答案已经解释了你是如何编译Cython代码而不是执行它的.但是,我想你可能想知道Cython可以让代码快多少.当我编译你拥有的代码(虽然我从不同的模块运行函数)时distutils,我获得了比直接Python更快的速度 - 大约1%.但是,当我在代码中添加一些小的更改时:

def test(long long value):
    cdef long long i
    cdef long long z
    for i in xrange(value):
        z = i**2
        if(i==1000000):
            print i
        if z < i:
            print "yes"
Run Code Online (Sandbox Code Playgroud)

编译它,我有以下几次:

  • 纯Python代码: 20.4553578737秒
  • Cython代码: 0.199339860234秒

这是一个100倍的加速.不是太寒酸.

  • 它可能以正确的代价来实现.Python代码计算`i**2`的正确值.如果您正在编译32位代码,则对于您执行操作的大多数数字,C代码会溢出.(如果它完全执行操作.可以想象你的C编译器完全优化了操作.)这可能不是一个公平的比较.你还没有完全清楚你正在运行什么,你如何运行它,以及当你给出那些时间时你的计划. (31认同)
  • 你是对的.我在做这件事时想到了溢出,但是很懒,因为我知道在这种情况下它并不重要.我会修复它使用long longs. (7认同)

Ste*_*ven 18

Cython不是另一个翻译.它从python(类似)代码生成python的c扩展.cython test.pyx将只生成一个'test.c'文件,它(一旦编译完成)可以被python使用,就像普通的python库一样.

这意味着您只测量cython将您的python代码转换为c所需的时间,而不是该代码版本的运行速度.

  • 是的,对于任何希望cython实际编译并在一行中运行程序的人,我创建了runcython(https://github.com/russell91/runcython).`runcython test.pyx`将具有OP意图的语义. (4认同)

Mik*_*ham 9

  • cython test.pyx实际上并没有运行你的程序.该cython二进制文件是处理你用Cython代码转换为Python扩展模块.您必须在Python中导入它才能运行它.

  • #!/usr/bin/python不是Python脚本最好的shebang系列.#!/usr/bin/env python通常是首选,它运行python命令行上的任何操作.

    • Cython pyx文件可能根本不应该有一个shebang行,除非它们是有效的Python程序.
  • 发布的代码中有IndentationError.

  • 使用传统的解释器更简单,更便携.Cython是可靠的,但有其局限性和怪癖.如果神奇地给你的加速时间让它看起来像那样,那么使用它可能会更有吸引力,但它实际上会给出更小的速度.您必须开始使用特定于Cython的功能来使用C功能来查看大量的加速.


car*_*arl 9

似乎缺少一个重点:Cython不是Python的严格超集.Python支持一些功能,但Cython没有.最值得注意的是,发电机和lambdas(但它们即将到来).

  • 你知道他们来了吗? (2认同)