将 numba 用于树结构的准则是什么?
What are the guidelines for using numba for a tree structure?
编辑:不止一次忘记 运行 numba(糟糕!)
我已经将 namedtuple 和 Dict 的 numba 版本视为潜在的解决方案,但与它们的 python 对应版本相比,它们似乎慢得多(大约慢 10000 倍)。
import time
from numba import njit
from collections import namedtuple
Alpha = namedtuple("Alpha", ["a", "b", "c"])
Regions = namedtuple("Regions", ["a", "b"])
State = namedtuple("State", ["H", "L"])
Parameters = namedtuple("Parameters", ["alpha", "DB", "beta", "psi", "pi", "CC_opt"])
def timer_func(func):
def function_timer(*args, **kwargs):
start = time.time()
value = func(*args, **kwargs)
end = time.time()
runtime = end - start
msg = "{func} took {time} seconds to complete its execution."
print(msg.format(func=func.__name__, time=runtime))
return value
return function_timer
@timer_func
def build_params() -> Parameters:
alpha = Regions(
a=Alpha(0.5, 0.5, 0),
b=Alpha(0.5, 0.5, 0),
)
return Parameters(alpha=alpha, DB=State(0.0, 0.0), beta=0.8, psi=0.0, pi=0.5, CC_opt=1.0)
@timer_func
@njit
def build_params_numba() -> Parameters:
alpha = Regions(
a=Alpha(0.5, 0.5, 0),
b=Alpha(0.5, 0.5, 0),
)
return Parameters(alpha=alpha, DB=State(0.0, 0.0), beta=0.8, psi=0.0, pi=0.5, CC_opt=1.0)
if __name__ == "__main__":
build_params()
build_params_numba()
build_params 花费 3.814697265625e-06 秒完成执行。
build_params_numba 花费了 0.07473492622375488 秒来完成它的执行。
编辑:
build_params_numba 花费了 3.5762786865234375e-06 秒来完成它的执行。
最大的问题是您正在测量 build_params_numba
的第一次执行,其中包括编译(它是即时编译的,正如您所要求的)。这就像测量一顿经典餐和微波炉餐之间的晚餐时间,但您将购买和安装微波炉的时间作为后者的一部分包括在内。 Measure the second invocation of build_params_numba
,当编译已经完成后,查看编译后的函数性能如何。
第二个问题是 numba
可能对您的代码没有多大帮助。据我所知,它旨在加速数值算法和 numpy 代码。必然地,namedtuple
和 dict
是 Python 数据结构,numba
必须这样对待它们;因此,即使您请求了 nopython 模式,Numba 也无法满足,因为它仅在可以检测到代码中所有值的本机数据类型时才有效(我认为——尽管在这一点上不是 100% 确定)。
编辑:不止一次忘记 运行 numba(糟糕!)
我已经将 namedtuple 和 Dict 的 numba 版本视为潜在的解决方案,但与它们的 python 对应版本相比,它们似乎慢得多(大约慢 10000 倍)。
import time
from numba import njit
from collections import namedtuple
Alpha = namedtuple("Alpha", ["a", "b", "c"])
Regions = namedtuple("Regions", ["a", "b"])
State = namedtuple("State", ["H", "L"])
Parameters = namedtuple("Parameters", ["alpha", "DB", "beta", "psi", "pi", "CC_opt"])
def timer_func(func):
def function_timer(*args, **kwargs):
start = time.time()
value = func(*args, **kwargs)
end = time.time()
runtime = end - start
msg = "{func} took {time} seconds to complete its execution."
print(msg.format(func=func.__name__, time=runtime))
return value
return function_timer
@timer_func
def build_params() -> Parameters:
alpha = Regions(
a=Alpha(0.5, 0.5, 0),
b=Alpha(0.5, 0.5, 0),
)
return Parameters(alpha=alpha, DB=State(0.0, 0.0), beta=0.8, psi=0.0, pi=0.5, CC_opt=1.0)
@timer_func
@njit
def build_params_numba() -> Parameters:
alpha = Regions(
a=Alpha(0.5, 0.5, 0),
b=Alpha(0.5, 0.5, 0),
)
return Parameters(alpha=alpha, DB=State(0.0, 0.0), beta=0.8, psi=0.0, pi=0.5, CC_opt=1.0)
if __name__ == "__main__":
build_params()
build_params_numba()
build_params 花费 3.814697265625e-06 秒完成执行。
build_params_numba 花费了 0.07473492622375488 秒来完成它的执行。
编辑:
build_params_numba 花费了 3.5762786865234375e-06 秒来完成它的执行。
最大的问题是您正在测量 build_params_numba
的第一次执行,其中包括编译(它是即时编译的,正如您所要求的)。这就像测量一顿经典餐和微波炉餐之间的晚餐时间,但您将购买和安装微波炉的时间作为后者的一部分包括在内。 Measure the second invocation of build_params_numba
,当编译已经完成后,查看编译后的函数性能如何。
第二个问题是 numba
可能对您的代码没有多大帮助。据我所知,它旨在加速数值算法和 numpy 代码。必然地,namedtuple
和 dict
是 Python 数据结构,numba
必须这样对待它们;因此,即使您请求了 nopython 模式,Numba 也无法满足,因为它仅在可以检测到代码中所有值的本机数据类型时才有效(我认为——尽管在这一点上不是 100% 确定)。