Python 有减速代码吗?
使用Python 有减速代码吗?,python,performance,numba,Python,Performance,Numba,使用numba 今天我发现有人在写一篇文章,他想加速他的代码。所以我想让我们来看看使用numba可以实现什么 代码如下: from numba import autojit from time import time LIMIT = pow(10,6) def primes(limit): # Keep only odd numbers in sieve, mapping from index to number is # num = 2 * idx + 3 # Th
numba
今天我发现有人在写一篇文章,他想加速他的代码。所以我想让我们来看看使用numba
可以实现什么
代码如下:
from numba import autojit
from time import time
LIMIT = pow(10,6)
def primes(limit):
# Keep only odd numbers in sieve, mapping from index to number is
# num = 2 * idx + 3
# The square of the number corresponding to idx then corresponds to:
# idx2 = 2*idx*idx + 6*idx + 3
sieve = [True] * (limit // 2)
prime_numbers = set([2])
for j in range(len(sieve)):
if sieve[j]:
new_prime = 2*j + 3
prime_numbers.add(new_prime)
for k in range((2*j+6)*j+3, len(sieve), new_prime):
sieve[k] = False
return list(prime_numbers)
numba_primes = autojit(primes)
start = time()
numba_primes(LIMIT)
end=time()
print("Numba: Time Taken : ",end-start)
start = time()
primes(LIMIT)
end=time()
print("Python: Time Taken : ",end-start)
结果是:
('Numba: Time Taken : ', 0.68790602684021)
('Python: Time Taken : ', 0.12417221069335938)
为什么会这样?似乎有了
numba
这段代码并没有变得更快 这是您的代码的一个numba-ized版本(使用numba 0.13),它通过使用numpy数组进行了优化
import numpy as np
import numba
# You could also just use @numba.jit or @numba.jit(nopython=True)
# here and get comparable timings.
@numba.jit('void(uint8[:])', nopython=True)
def primes_util(sieve):
ssz = sieve.shape[0]
for j in xrange(ssz):
if sieve[j]:
new_prime = 2*j + 3
for k in xrange((2*j+6)*j+3, ssz, new_prime):
sieve[k] = False
def primes_numba(limit):
sieve = np.ones(limit // 2, dtype=np.uint8)
primes_util(sieve)
return [2] + (np.nonzero(sieve)[0]*2 + 3).tolist()
然后与计时进行比较:
In [112]: %timeit primes(LIMIT)
1 loops, best of 3: 221 ms per loop
In [113]: %timeit primes_numba(LIMIT)
100 loops, best of 3: 11 ms per loop
In [114]:
a = set(primes(LIMIT))
b = set(primes_numba(LIMIT))
a == b
Out[114]:
True
这是20倍的加速,尽管可能还有进一步的优化。如果没有jit装饰器,numba版本在我的机器上运行大约300毫秒。对
primes\u util
的实际调用只需要大约5毫秒,其余的调用是对np.nonzero
的调用以及到列表的转换。第一个问题-您使用的是哪个版本的Numba。在0.11和0.12之间进行了一次重大的重构,通过大量的性能/特性回归,事情的表现发生了巨大的变化。此外,Numba不会加速任意python代码。它在处理numpy阵列的循环中发挥了神奇的作用。您不会期望看到操纵python对象的性能有多高。注意,你的问题和杰克的问题在这方面完全不同,我用的是0.13。是的,你是对的。在使用数组时,numba似乎得到了最多的好处。在您的代码中,您希望编写没有x的np.nonzero(sieve)