【发布时间】:2019-03-22 00:22:50
【问题描述】:
目前我正在尝试提高我的 python 代码的性能。为此,我成功地使用了 numba。为了改进我的代码结构,我创建了函数。现在我惊讶地注意到,如果我将代码拆分为不同的 numba 函数,代码比我将整个代码放在一个带有 numba 装饰器的函数中要慢得多。 一个例子是:
@nb.njit
def fct_4(a, b):
x = a ^ b
setBits = 0
while x > 0:
setBits += x & 1
x >>= 1
return setBits
@nb.njit
def fct_3(c, set_1, set_2):
h = 2
if c not in set_1 and c not in set_2:
if fct_4(0, c) <= h:
set_1.add(c)
else:
set_2.add(c)
@nb.njit
def fct_2(c, set_1, set_2):
fct_3(c, set_1, set_2)
@nb.njit
def fct_1(set_1, set_2):
for x1 in range(1000):
c = 2
fct_2(c, set_1, set_2)
比
慢@nb.njit
def fct_1(set_1, set_2):
for x1 in range(1000):
c = 2
h = 2
if c not in set_1 and c not in set_2:
if fct_4(0, c) <= h:
set_1.add(c)
else:
set_2.add(c)
与
@nb.njit
def main_fct(set_1, set_2):
for i in range(50):
for x in range(1000):
fct_1(set_1, set_2)
set_1 = {0}
set_2 = {47}
start = timeit.default_timer()
main_fct(set_1, set_2)
stop = timeit.default_timer()
(2.70 秒对 0.46 秒)。我认为这不应该有所作为。你能启发我吗?
【问题讨论】:
-
1) 您测量运行时和编译时间的混合。在计时之前运行一次函数以获得运行时。 2) LLVM 后端决定是内联函数还是调用它,如果函数没有内联,则预期会有差异。 3)对于一个小例子,你的功能真的很复杂。 Numba 不能直接处理列表或字典,它们被转换为非常昂贵的内部表示。也许这种开销没有针对嵌套函数进行优化,导致性能不佳。
-
我可以强制 LLVM 倾斜函数吗?签名有用吗?我应该避免使用集合吗?