Python类的性能影响:科学计算

时间:2017-09-23 04:23:15

标签: python performance numpy numba

所以我正在编写一个粒子模型。此模拟将涉及创建具有物种索引(以识别粒子类型)和3D空间中的位置/速度等属性的多个粒子。它还将具有基于其在模拟运行期间计算的空间内的位置的属性。我之前使用巨型numpy数组运行此模型,其中每行对应一个粒子,每列对应粒子属性。

我的主要问题是:如果我要创建一个类"粒子"这样我就可以生成代表每个粒子的实例,在计算速度方面是否有性能损失?如果我想运行一个包含一百万个粒子的程序,将所有数字放在一个大数组中是否更有效(即使它不是那么可读),或者使用它的实例效率也一样高效class,并在模拟过程中修改实例属性?或者是类很好,但是将许多类实例存储在Python列表/ NumPy数组中确实会减慢执行速度?

顺便说一下,这个程序将与python模块一起使用" Numba"对数值计算有很多优化(特别是通过像jitclass http://numba.pydata.org/numba-doc/latest/user/jitclass.html#numba.jitclass这样的东西)。但是,我不想通过在模拟中声明导致其无效运行的变量来破坏此模块的性能优势。

谢谢!

2 个答案:

答案 0 :(得分:2)

  

我之前使用巨型numpy数组运行此模型

听起来不错。

  

如果我要创建一个类"粒子"这样我就可以生成代表每个粒子的实例,在计算速度方面是否有性能损失?

可能会慢很多。

使用NumPy阵列的现有解决方案可让您在一个大阵列中表示所有粒子:

id species x y z dx dy dz
id species x y z dx dy dz
id species x y z dx dy dz

如果你改变它以使用每个粒子的类实例,你仍然可以将它们保存在NumPy数组(或列表)中,但是它将如下所示:

object -> [id species x y z dx dy dz]
object -> [id species x y z dx dy dz]
object -> [id species x y z dx dy dz]

你需要分配的四个N + 1个对象而不是1个(数组)。

我坚持使用原始设计 - 巨型NumPy阵列,除非它造成重大问题。

答案 1 :(得分:0)

您应该在这里使用结构化数据类型:

particle_dtype = np.dtype([
    ('id', int),
    ('species', (np.unicode_, 16)),
    ('pos', np.float32, 3),
    ('vel', np.float32, 3)
])

particles = np.empty(100, dtype=particle_dtype)
particles[0]['id'] = 1
particles['pos'] += particles['vel'] * dt