【发布时间】:2023-01-30 20:23:43
【问题描述】:
我在 Python+Numpy 和 Matlab 中运行相同的测试代码,发现 Matlab 代码的速度快了一个数量级。我想知道 Python 代码的瓶颈是什么以及如何加快速度。
我使用 Python+Numpy 运行以下测试代码(最后一部分是性能敏感部分):
# Packages
import numpy as np
import time
# Number of possible outcomes
num_outcomes = 20
# Dimension of the system
dim = 50
# Number of iterations
num_iterations = int(1e7)
# Possible outcomes
outcomes = np.arange(num_outcomes)
# Possible transition matrices
matrices = [np.random.rand(dim, dim) for k in outcomes]
matrices = [mat/np.sum(mat, axis=0) for mat in matrices]
# Initial state
state = np.random.rand(dim)
state = state/np.sum(state)
# List of samples
samples = np.random.choice(outcomes, size=(num_iterations,))
samples = samples.tolist()
# === PERFORMANCE-SENSITIVE PART OF THE CODE ===
# Update the state over all iterations
start_time = time.time()
for k in range(num_iterations):
sample = samples[k]
matrix = matrices[sample]
state = np.matmul(matrix, state)
end_time = time.time()
# Print the execution time
print(end_time - start_time)
然后我使用 Matlab 运行等效代码(最后一部分是对性能敏感的部分):
% Number of possible outcomes
num_outcomes = 20;
% Number of dimensions
dim = 50;
% Number of iterations
num_iterations = 1e7;
% Possible outcomes
outcomes = 1:num_outcomes;
% Possible transition matrices
matrices = rand(num_outcomes, dim, dim);
matrices = matrices./sum(matrices,2);
matrices = num2cell(matrices,[2,3]);
matrices = cellfun(@shiftdim, matrices, 'UniformOutput', false);
% Initial state
state = rand(dim,1);
state = state./sum(state);
% List of samples
samples = datasample(outcomes, num_iterations);
% === PERFORMANCE-SENSITIVE PART OF THE CODE ===
% Update the state over all iterations
tic;
for k = 1:num_iterations
sample = samples(k);
matrix = matrices{sample};
state = matrix * state;
end
toc;
Python 代码始终比 Matlab 代码慢一个数量级,我不确定为什么。
知道从哪里开始吗?
我使用 Python 3.10 解释器和 Numpy 1.22.4 运行 Python 代码。我使用 Matlab R2022a 运行 Matlab 代码。这两个代码都在具有以下处理器的 Lenovo T14 ThinkPad 上的 Windows 11 Pro 64 位上运行:
第 11 代 Intel(R) Core(TM) i7-1165G7 @ 2.80GHz,2803 Mhz,4 核,8 逻辑处理器
编辑 1:我做了一些额外的测试,看起来罪魁祸首是某种类型的 Python 特定的低矩阵大小的常量开销:
正如 hpaulj 和 MSS 所建议的,这可能意味着 JIT 编译器可以解决其中的一些问题。我会在不久的将来尽我所能尝试这个。
编辑 2:我在 Pypy 下运行了代码,虽然它确实改变了缩放比例,甚至在小矩阵尺寸下击败了 Cpython,但它通常会为这个特定代码带来很大的开销:
因此,如果有减轻这种开销的方法,JIT 编译器可能会有所帮助。否则,Cython 实现可能是剩下的路要走......
【问题讨论】:
-
看起来你基本上是在问为什么(专有理由)垫里克斯实验室oritory 比 Python 重复做更快矩阵操作?
-
对不起,但这不是问题的答案。我非常了解 Matlab。但这不是问题。问题是:为什么它变慢了,我能做些什么来改进 Python 代码。
-
我知道这不是答案,这就是为什么我把它留作评论的原因。 MATLAB 是非常擅长设计矩阵运算,这个网站上有很多几乎重复的问题问类似的事情
-
好吧,我明白了。然后就这么说,也许让我参考这样一个重复的问题,并且请听起来不那么居高临下(重新阅读您的评论并想象您是那个得到它的人)。这对每个人来说都会好得多。别往心里放。
-
第一个评论不是修辞,我认为这让它看起来不那么居高临下。我正在寻求确认这是否从根本上就是您要问的,因为无法运行 Python 代码就是您的示例给人的印象。如果是这样的话,我还强调了 MATLAB 通常只是为了从根本上快速进行矩阵运算而设计的。有lots of related questions,有时是列顺序或内存分配,有时只是矩阵运算
标签: python numpy performance matlab