4

简洁版本

如果我有这样的矩阵:

1  2
3  4

在内存中,它是存储为[1 2 3 4]还是[1 3 2 4]. 换句话说,矩阵是针对访问还是列访问更优化


长版

我正在将一些代码从 Matlab 翻译成 NumPy。我习惯于多维数组的 C 约定(即最后一个索引非常快,矩阵按行存储),这是NumPy 数组的默认设置。但是,在 Matlab 代码中,我总是看到这样的片段(用于在单个多维数组中排列多个彩色图像):

images(:, :, :, i) = im

这对于 C 约定看起来不是最理想的,并且对于 FORTRAN 约定更优化(第一个索引非常快速,矩阵按列存储)。那么,Matlab 使用第二种风格并且对列操作进行了更好的优化是否正确?

4

2 回答 2

5

简短的回答:它是按列存储的。

A = [1 2; 3 4];
A(:) = [1; 3; 2; 4];

在许多情况下,如果您以“正确的顺序”进行计算,并对整列而不是行进行操作,性能会好得多。

一个简单的例子:

%% Columns
a = rand(n);
b = zeros(n,1);
tic
for ii = 1:n
  b = b + a(:,ii);
end
toc
Elapsed time is 0.252358 seconds.

%% Rows:
a = rand(n);
b = zeros(1,n);
tic
for ii = 1:n
  b = b + a(ii,:);
end
toc
Elapsed time is 2.593381 seconds.

处理列时速度提高 10 倍以上!

于 2013-09-02T21:02:52.547 回答
-1
%% Columns
n = 4000;

a = rand(n);
b = zeros(n,1);
tic
for j = 1 : 10
 for ii = 1:n
  b = b + a(:,ii);
 end
end
toc


%% Rows new:
a = rand(n);
b = zeros(1,n);
tic
for j = 1 : 10
 for ii = 1:n
  b = b + a(ii);
 end
end
toc

%% Rows old:
a = rand(n);
b = zeros(1,n);
tic
for j = 1 : 10
 for ii = 1:n
  b = b + a(ii,:);
 end
end
toc

结果:

经过的时间是 1.53509 秒。

经过的时间是 1.03306 秒。

经过的时间是 3.4732 秒。

所以看起来在行上工作比在列上工作要快一点,但是使用:会导致速度变慢。

于 2016-05-13T06:41:48.533 回答