设计与 `scipy.integrate.odeint` 交互的 Python 类 的启发式方法?
Design heuristics for writing Python classes that interact with `scipy.integrate.odeint`?
简介
scipy.integrate.odeint
需要一个函数作为其第一个参数,该函数计算我们要积分的变量的导数(我将其称为 d_func
,因为 "derivative function"今后)。
d_func
必须由用户在 Python 代码中编写。使用 Numba 提高性能的一个好方法是 @jit
d_func
(因为 d_func
在集成期间被调用 很多 次)。
我对如何在 d_func
复杂到需要 Python class 对象的情况下编写高性能代码有疑问。
代码设置
这是我的代码 "cartoon":
- 有一个名为
DynamicBox.py
的模块
- 这个模块里面有一个Pythonclass,
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都不是
动态框.
问题
我对 Python 的了解还不够,无法找出最佳选择。我认为需要回答以下问题。
进行实例属性调用以获取属性是昂贵的还是仅当您在不是方法的函数中时才昂贵
class?
如果使用 Numba 怎么办?例如,如果我使用 @jit
-ting 普通函数而不是 class 方法,Numba 会更喜欢它吗?
我可以评论这个问题的 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
参数,如果函数必须回退到任何(慢速),这将导致 Numba 引发错误) Python 代码。这个 nopython
参数是确保您的 Numba 函数尽可能高效的好方法。
简介
scipy.integrate.odeint
需要一个函数作为其第一个参数,该函数计算我们要积分的变量的导数(我将其称为 d_func
,因为 "derivative function"今后)。
d_func
必须由用户在 Python 代码中编写。使用 Numba 提高性能的一个好方法是 @jit
d_func
(因为 d_func
在集成期间被调用 很多 次)。
我对如何在 d_func
复杂到需要 Python class 对象的情况下编写高性能代码有疑问。
代码设置
这是我的代码 "cartoon":
- 有一个名为
DynamicBox.py
的模块
- 这个模块里面有一个Pythonclass,
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都不是 动态框.
问题
我对 Python 的了解还不够,无法找出最佳选择。我认为需要回答以下问题。
进行实例属性调用以获取属性是昂贵的还是仅当您在不是方法的函数中时才昂贵 class?
如果使用 Numba 怎么办?例如,如果我使用
@jit
-ting 普通函数而不是 class 方法,Numba 会更喜欢它吗?
我可以评论这个问题的 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
.
做同样事情的更好方法是:
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
参数,如果函数必须回退到任何(慢速),这将导致 Numba 引发错误) Python 代码。这个 nopython
参数是确保您的 Numba 函数尽可能高效的好方法。