【问题标题】:Numba slowing Code?Numba 减慢代码?
【发布时间】:2014-03-31 17:54:05
【问题描述】:

HERE 使用 numba 获得的加速让我印象深刻

今天,我在 SO 中找到了一个 question,来自一个希望加速其代码的人。所以我想让我们看看使用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。在 0.11 和 0.12 之间进行了重大重构,通过许多性能/功能回归改变了事物的行为方式。
  • 此外,Numba 不会加速任意 python 代码。它对处理 numpy 数组的 for 循环确实有奇效。您不会期望看到操纵 python 对象的性能。请注意,您的问题和 Jake 的问题在这方面完全不同。

标签: python performance numba


【解决方案1】:

这是您的代码的 numba 化版本(使用 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_util 的实际调用只需要大约 5 毫秒,剩下的就是对np.nonzero 的调用和对列表的转换。

【讨论】:

  • 我使用 numba 0.13。是的你是对的。似乎 numba 在处理数组时获得了最大的收益。在你的代码中你想写 np.nonzero(sieve) 没有 x
猜你喜欢
  • 2014-02-23
  • 1970-01-01
  • 2018-11-12
  • 1970-01-01
  • 1970-01-01
  • 2021-03-10
  • 1970-01-01
  • 2022-06-15
  • 2018-03-15
相关资源
最近更新 更多