仿真建模的一个重要部分是仿真运行时间。大型离散事件仿真模型甚至中型基于代理的仿真模型会消耗计算资源,并且运行时间可能很长。如果源代码完全用 Python 编写,则尤其如此。因此,我在 Python 中使用 Numba 进行了一些测试。我在这里分享我的结果。首先,我在 Python 中对一个测试函数运行一个简单的测试。之后,我总结了将 Numba 应用到 Python 中基于代理的建模框架后的运行时性能改进。
在 Python 中安装 Numba
可以使用 pip install 命令安装 Numba。只需在终端中输入以下内容:
pip install numba
对于列表,我建议您使用numpy(即numpy数组),因为这将允许您避免使用默认的Python list。如果尚未安装,您可以以相同的方式安装 numy:
pip install numpy
您现在可以导入numpy和 numba 并使用 numba 使您的代码运行得更快。为此,您可以使用@njit装饰器。
在 Python 中测试 Numba 性能改进
是时候看看 Python 中的一个简单的运行时改进测试了。下面的代码实现了 Numba 以获得更快的 Python 程序。
import numpy as np
from numba import jit
import random
import time
def rand_events(n: int) -> np.ndarray:
ls = np.zeros(n)
for i in range(n):
x = random.random()
while True:
y = random.random()
if x < y:
ls[i] = y
break
return ls
""" RUNTIME TEST WITHOUT NUMBA -------------------------- """
_start_time = time.time()
vals = rand_events(10000000)
_end_time = time.time()
print(str(_end_time - _start_time))
""" RUNTIME TEST WITH NUMBA ------------------------------ """
_start_time = time.time()
jit_rand_events = jit(nopython=True)(rand_events)
vals = jit_rand_events(10000000)
_end_time = time.time()
print(str(_end_time-_start_time))
_start_time = time.time()
vals = jit_rand_events(10000000)
_end_time = time.time()
print(str(_end_time-_start_time))
在上面的代码中调用 jit(nopython=True) 等于使用@njit声明符。运行上述代码时,终端中的输出将类似于以下内容(取决于机器和随机数生成结果)
9.1829195022583 1.2913379669189453 0.8751001358032227
这意味着调用 n = 10,000,000 的 rand_events() 函数需要 9.18 秒。应用@njit声明器并再次运行该函数后,仅需 1.29 秒(包括“抖动”该函数)。如果没有@njit声明器的调用,调用 rand_events() 的“jitted”版本需要 0.87 秒。这是一个显着的运行时改进。
应用 Numba 进行更快的 Python 模拟
Numba 可以使模拟框架更快。但前提是框架的主要部分是面向数字的。此外,框架应该集成numpy,因为 numba非常了解numpy 。在一个强面向对象的框架中,这可能是一个挑战。但是,如果您能够设法将代码的计算密集型部分转换为数字代码,那么 numba 可以显着提高 Python 代码的运行时性能。
专业领域为优化和仿真的工业工程师(R,Python,SQL,VBA)
Leave a Reply