Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 返回语句时速度较慢_Python_Performance_Return_Cython - Fatal编程技术网

Python 返回语句时速度较慢

Python 返回语句时速度较慢,python,performance,return,cython,Python,Performance,Return,Cython,我有这个cython代码只是为了测试: cimport cython cpdef loop(int k): return real_loop(k) @cython.cdivision cdef real_loop(int k): cdef int i cdef float a for i in xrange(k): a = i a = a**2 / (a + 1) return a 我用这样的脚本测试了cython代码

我有这个cython代码只是为了测试:

cimport cython

cpdef loop(int k):
    return real_loop(k)

@cython.cdivision
cdef real_loop(int k):
    cdef int i
    cdef float a
    for i in xrange(k):
        a = i
        a = a**2 / (a + 1)
    return a
我用这样的脚本测试了cython代码和纯python中相同代码的速度差异:

import mymodule

print(mymodule.loop(100000))
我的速度快了80倍。但是如果我删除cython代码中的两个return语句,速度会快800-900倍。为什么?

另一件事是,如果我在我的旧ACER Aspire ONE笔记本电脑上运行此代码(带return),我的速度将提高700倍,在家里的新台式i7电脑上运行此代码的速度将提高80倍


有人知道为什么吗?

我用以下代码测试了您的问题:

#cython: wraparound=False
#cython: boundscheck=False
#cython: cdivision=True
#cython: nonecheck=False
#cython: profile=False

def loop(int k):
 return real_loop(k)

def loop2(int k):
 cdef float a
 real_loop2(k, &a)
 return a

def loop3(int k):
    real_loop3(k)
    return None

def loop4(int k):
    return real_loop4(k)

def loop5(int k):
 cdef float a
 real_loop5(k, &a)
 return a

cdef float real_loop(int k):
    cdef int i
    cdef float a
    a = 0.
    for i in range(k):
        a += a**2 / (a + 1)
    return a

cdef void real_loop2(int k, float *a):
    cdef int i
    a[0] = 0.
    for i in range(k):
        a[0] += a[0]**2 / (a[0] + 1)

cdef void real_loop3(int k):
    cdef int i
    cdef float a
    a = 0.
    for i in range(k):
        a += a**2 / (a + 1)

cdef float real_loop4(int k):
    cdef int i
    cdef float a
    a = 0.
    for i in range(k):
        a += a*a / (a + 1)
    return a

cdef void real_loop5(int k, float *a):
    cdef int i
    a[0] = 0.
    for i in range(k):
        a[0] += a[0]*a[0] / (a[0] + 1)
其中,
real\u loop()
与您的函数很接近,因为原来的公式看起来很奇怪,所以对
a
的公式进行了修改

函数
real\u loop2()
没有返回任何值,只是通过引用更新
a

函数
real\u loop3()
未返回任何值

检查生成的
C
代码的
real\u loop3()
可以看到循环在那里,代码被称为。。。但我的结论与@dmytro相同,改变
k
不会显著改变时间。。。所以这里一定有一点我遗漏了

从下面的计时可以看出,
return
不是瓶颈,因为
real\u loop2()
real\u loop5()
没有返回任何值,它们的性能分别与
real\u loop4()
相同

In [2]: timeit _stack.loop(100000)
1000 loops, best of 3: 1.71 ms per loop

In [3]: timeit _stack.loop2(100000)
1000 loops, best of 3: 1.69 ms per loop

In [4]: timeit _stack.loop3(100000)
10000000 loops, best of 3: 78.5 ns per loop

In [5]: timeit _stack.loop4(100000)
1000 loops, best of 3: 913 µs per loop

In [6]: timeit _stack.loop5(100000)
1000 loops, best of 3: 979 µs per loop

请注意,
a*a
a**2
的~2X加速更改,因为
a**2
需要在循环内部调用函数
powf()

很难说——我想知道编译器是否足够聪明,可以看到
real\u loop
不会更新任何全局变量,也不会更改任何参数,因此可以将其转换为禁止操作。您是否尝试
diff
两个生成的C文件以查看差异?不管怎么说,可能是因为cython发现没有返回的函数是无用的,根本不会循环。@Bakuriu是的,我就是这么想的。可能根本不做循环。我不知道怎么写,但昨天当我尝试用不同的方式编写代码时,我得到了一些可笑的性能,比如说快了12000倍。这实在是太多了。这意味着编译器将整个循环替换为一个no-op。如果所用时间不随输入大小而变化,您应该看到这一点。这些系统上可能有不同的编译器。在我的带有gcc4.7.2的Corei5笔记本电脑上,mymodule.loop(N)总是需要约120纳秒,不管N有多大,也就是说,它跳过了循环。