scipy.integrate.odeint
需要作为其第一个参数,一个计算我们想要整合的变量的导数的函数(我将其称为d_func
,从现在开始计算“衍生函数” )。
d_func
必须由用户在Python代码中编写。使用Numba提升性能的一个好方法是@jit
d_func
(因为d_func
在集成期间被称为很多次。)
当d_func
足够复杂以至于需要一个Python类对象时,我对如何编写高性能代码有疑问。
这是我的代码的“卡通片”:
DynamicBox.py
DynamicBox
DynamicBox
有一堆属性我将拥有一系列将采用DynamixBox
阶段变量或参数属性的函数,以便计算衍生函数中的相关项。那就是:
d_func
d_func
本身会调用许多小辅助函数
使用DynamixBox
计算衍生工具中的相关字词
属性我必须做出选择,并提供以下选项:
d_func
及其所有辅助函数方法
DynamicBox
; d_func
DynamicBox
的方法,
并且它的所有辅助函数都在同一个模块中
DynamicBox
,但不是DynamicBox
; DynamicBox
的方法,但是
d_func
位于同一模块(DynamicBox.py
)中,而不是a
DynamicBox
; 我不太了解Python以确定哪个选择最佳。我认为需要回答以下问题。
使实例属性调用获取属性是否昂贵,或者仅当您处于不是方法的函数时才会很昂贵 班级?
如果Numba在比赛中怎么办?例如,如果我@jit
- 正常函数而不是类方法,Numba会更喜欢它吗?
答案 0 :(得分:2)
我可以评论这个问题的Numba部分。
正如其他用户所提到的,Numba中的属性访问会导致一些开销。例如,您可能想要编写如下代码:
class Foo(object):
def __init__(self, x):
self.x = x
@numba.jit
def dosomething(self, y):
for i in range(len(self.x)):
self.x[i] += y[i]
这将很慢,因为Numba每次遇到self.x
时都必须调用Python层进行属性访问。
做同样事情的更好方法是:
class Foo(object):
def __init__(self, x):
self.x = x
def dosomething(self, y):
_dosomething(self.x, y)
@numba.jit(nopython=True)
def _dosomething(x, y):
for i in range(len(x)):
x[i] += y[i]
这里循环中没有属性访问,另外我们能够添加nopython=True
参数,如果函数必须回退到任何(慢)Python,这将导致Numba引发错误码。这个nopython
参数是确保您的Numba函数尽可能高效的好方法。