简介
scipy.integrate.odeint需要作为其第一个参数,一个计算我们想要整合的变量的导数的函数(从现在开始,我将其称为 d_func
,"derivative function") .
d_func
必须由用户在Python代码中编写 . 使用Numba提高性能的一个好方法是 @jit
(因为在集成期间多次调用 d_func
) .
当 d_func
足够复杂以至于需要一个Python类对象时,我对如何编写高性能代码有疑问 .
代码设置
这是我的代码的“卡通”:
-
有一个名为
DynamicBox.py
的模块 -
这个模块里面是一个Python类,
DynamicBox
-
DynamicBox
有一堆属性 -
其中一些属性是"phase variables" - 也就是说,它们是我有兴趣整合的数量
-
这些属性中的一些是"parameters" - 也就是说,我用它们来计算相位变量的导数
我将有一堆函数将采用 DynamixBox
阶段变量或参数属性,以便计算衍生物中的相关项 . 那是:
-
我会
d_func
-
d_func
本身将使用DynamixBox
属性调用许多小辅助函数来计算导数中的相关项
设计选择
我必须做出选择,有以下选择:
-
或者我可以使
d_func
及其所有辅助函数方法DynamicBox
; -
或者我只能使
d_func
的方法DynamicBox
,并且它的所有辅助函数与DynamicBox
在同一个模块中,但不是DynamicBox
的方法; -
或只有辅助函数是
DynamicBox
的方法,但d_func
只是在同一个模块(DynamicBox.py
)中,而不是DynamicBox
的方法; -
或者辅助函数和d_func都不是DynamicBox的方法 .
问题
我不太了解Python以找出最佳选择 . 我认为需要回答以下问题 .
-
Is it expensive to make instance attribute calls to get attributes or is it expensive only if you are in a function that is not a method of the class?
-
What if Numba is in play? For instance, will Numba like it better if I am @jit-ting normal functions instead of class methods?
1 回答
我可以评论这个问题的Numba部分 .
正如其他用户所提到的,Numba中的属性访问会导致一些开销 . 例如,您可能想要编写如下代码:
这将是缓慢的,因为Numba每次遇到
self.x
时都必须调用Python层进行属性访问 .做同样事情的更好方法是:
这里循环中没有属性访问,另外我们能够添加
nopython=True
参数,如果函数必须回退到任何(慢)Python代码,这将导致Numba引发错误 . 这个nopython
参数是确保您的Numba功能尽可能高效的好方法 .