cpython vs cython vs numpy数组性能 [英] cpython vs cython vs numpy array performance
问题描述
我正在对 http://docs.cython中的质数生成器的变体进行性能测试. org/src/tutorial/numpy.html . 以下性能指标是kmax = 1000
I am doing some performance test on a variant of the prime numbers generator from http://docs.cython.org/src/tutorial/numpy.html. The below performance measures are with kmax=1000
在CPython中运行的纯Python实现:0.15秒
Pure Python implementation, running in CPython: 0.15s
在Cython中运行的纯Python实现:0.07秒
Pure Python implementation, running in Cython: 0.07s
def primes(kmax):
p = []
k = 0
n = 2
while k < kmax:
i = 0
while i < k and n % p[i] != 0:
i = i + 1
if i == k:
p.append(n)
k = k + 1
n = n + 1
return p
在CPython中运行的纯Python + Numpy实现:1.25秒
Pure Python+Numpy implementation, running in CPython: 1.25s
import numpy
def primes(kmax):
p = numpy.empty(kmax, dtype=int)
k = 0
n = 2
while k < kmax:
i = 0
while i < k and n % p[i] != 0:
i = i + 1
if i == k:
p[k] = n
k = k + 1
n = n + 1
return p
使用int *的Cython实现:0.003s
Cython implementation using int*: 0.003s
from libc.stdlib cimport malloc, free
def primes(int kmax):
cdef int n, k, i
cdef int *p = <int *>malloc(kmax * sizeof(int))
result = []
k = 0
n = 2
while k < kmax:
i = 0
while i < k and n % p[i] != 0:
i = i + 1
if i == k:
p[k] = n
k = k + 1
result.append(n)
n = n + 1
free(p)
return result
上面的代码表现不错,但看起来很恐怖,因为它保存了两个数据副本...所以我尝试重新实现它:
The above performs great but looks horrible, as it holds two copies of the data... so I tried reimplementing it:
Cython + Numpy:1.01秒
Cython + Numpy: 1.01s
import numpy as np
cimport numpy as np
cimport cython
DTYPE = np.int
ctypedef np.int_t DTYPE_t
@cython.boundscheck(False)
def primes(DTYPE_t kmax):
cdef DTYPE_t n, k, i
cdef np.ndarray p = np.empty(kmax, dtype=DTYPE)
k = 0
n = 2
while k < kmax:
i = 0
while i < k and n % p[i] != 0:
i = i + 1
if i == k:
p[k] = n
k = k + 1
n = n + 1
return p
问题:
- 为什么在CPython上运行时,numpy数组比python列表这么慢?
- 在Cython + Numpy实施中我做错了什么? cython显然没有将numpy数组作为应有的int []处理.
-
如何将numpy数组转换为int *?下面不起作用
- why is the numpy array so incredibly slower than a python list, when running on CPython?
- what did I do wrong in the Cython+Numpy implementation? cython is obviously NOT treating the numpy array as an int[] as it should.
how do I cast a numpy array to a int*? The below doesn't work
cdef numpy.nparray a = numpy.zeros(100, dtype=int)
cdef int * p = <int *>a.data
推荐答案
到目前为止找到的最佳语法:
Best syntax I found so far:
import numpy
cimport numpy
cimport cython
@cython.boundscheck(False)
@cython.wraparound(False)
def primes(int kmax):
cdef int n, k, i
cdef numpy.ndarray[int] p = numpy.empty(kmax, dtype=numpy.int32)
k = 0
n = 2
while k < kmax:
i = 0
while i < k and n % p[i] != 0:
i = i + 1
if i == k:
p[k] = n
k = k + 1
n = n + 1
return p
请注意我在这里使用numpy.int32而不是int. cdef左侧的任何内容均为C类型(因此int = int32和float = float32),而其右侧(或cdef外部)的任何内容均为python类型(int = int64和float = float64) )
Note where I used numpy.int32 instead of int. Anything on the left side of a cdef is a C type (thus int = int32 and float = float32), while anything on the RIGHT side of it (or outside of a cdef) is a python type (int = int64 and float = float64)
这篇关于cpython vs cython vs numpy数组性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!