问题描述
我正在用python做很多模拟,模拟系统响应.
I'm doing a lot of simulations with python, simulating system responses.
我目前一直在使用Runge-Kutta方案,但偶然发现了我正在测试的另一种方案.
I've currently been using a Runge-Kutta scheme, but have stumbled upon another scheme I've been testing.
在Matlab中进行测试时,与我的Runge-Kutta相比,我获得了出色的性能.但是,当我将其转移到Python时,它的速度明显慢了.
When testing this in Matlab I achieve exceptional performance, compared to that of my Runge-Kutta. However, when I transferred this to Python, it was significantly slower.
我不确定这是不是真的,或者我是否可以改善编码方式,所以如果可能的话,我想听听您的一些意见.
I'm not sure if this is just how it is, or if I could improve my way of coding, so I would love to hear some of your input, if possible.
Matlab中的代码示例:
The code in Matlab, exemplified:
dt = 0.0001;
f = randn(1, (60 / dt));
ns = length(f);
yo = zeros(3,1);
P1 = [0; 0.001; 0];
F = [1 0.0001 0; 0.001 1 0.0001; 0.001 0 1];
y1 = zeros(3, ns);
tic
for i = 1:ns
y1(:, i) = P1*f(:, i) + F*yo;
yo = y1(:, i);
end
toc
其中循环在0.55-0.61秒内执行.
In which the loop executes in 0.55-0.61 sec.
Python中的代码,例如:
The code in Python, exemplified:
dt = 0.0001
f = np.random.randn(1, int(60 / dt))
ns = np.size(f)
yo = np.zeros((3))
F = np.array([[1, 0.0001, 0], [0.001, 1, 0.0001], [0.001, 0, 1]])
P1 = np.transpose(np.array([[0, 0.0001, 0]]))
y1 = np.zeros((3, ns), order='F')
start_time = time.time()
for i in range(ns-1):
y1[:, i] = np.dot(P1, f[:, i]) + np.reshape(np.dot(F, yo), (3))
yo = y1[: , i]
print("--- %s seconds ---" % (time.time() - start_time))
其中循环在2.8 -3.1秒内执行.
In which the loop executes in 2.8 -3.1 sec.
我可以做些改进吗?
感谢您考虑我的问题.
推荐答案
我对您的代码进行了一些优化,对我来说,执行时间从2.8s减少到1.2s左右.在寻找更快的解释器之前,我建议您进行性能分析(请参阅line_profiler),并尝试从最内层循环中删除所有可能的内容.更好的方法是,尝试避免任何显式的"for"循环,并依赖于numpy函数,例如点,einsum等.
I optimized your code a bit, the execution time for me went from 2.8s down to around 1.2s. Before you look for faster interpreters I recommend you do profiling (see line_profiler) and try to remove everything you can out of the innermost loop. Better, try to avoid any explicit 'for' loops and rely on numpy functions such as dot, einsum, etc.
我想仍然有一些优化的地方.我认为我没有改变您的价值观,但请您检查一下.使用其他工具,例如numba或cython( cython.org )或pypy( pypy.org ),我想您的执行时间将会大大提高.
I guess there is still some place for optimization. I don't think I changed your values but better check. With other tools like numba or cython (cython.org) or pypy (pypy.org) I guess your execution time will improve quite a lot more.
#!/usr/bin/env python3
import numpy as np
import time
np.random.seed(0)
#@profile
def run():
dt = 0.0001
f = np.random.randn(1, int(60 / dt))
ns = np.size(f)
yo = np.zeros((3))
F = np.array([[1, 0.0001, 0], [0.001, 1, 0.0001], [0.001, 0, 1]])
P1 = np.transpose(np.array([[0, 0.0001, 0]]))
start_time = time.time()
y1 = np.outer(f, P1)
for i in range(ns-1):
y1[i] += F@yo
yo = y1[i]
print("--- %s seconds ---" % (time.time() - start_time))
y1 = y1.T
print(yo)
run()
这篇关于如何在python中提高for循环的性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!