在MATLAB中将行/列附加到矩阵似乎需要考虑。例如,当我尝试将列附加到具有许多行和多列的矩阵A
时,例如
A = [A, added_col]
Matlab会警告我,由于这必须在内存中复制A,我最好使用预分配来提高速度。这是可以理解的,因为A
中的基础数据占用了连续的内存块。
我的问题是,删除行/列会导致类似的问题吗?例如,要删除A
的第二行:
A(2,:) = []
此操作是否就地?我真的感到不确定,因为有一件事它似乎没有为内存中的数据创造任何新的空间,而另一方面,A
的行将被非连续地存储(因为第2行是去除)。
那么内部会发生什么?这项操作是否足以在实践中使用?谢谢!
刚刚使用100000
的复杂度进行了测试:
clc; clear;
N = 100000;
A = zeros(N, 3);
t1 = tic;
for ii = 1:N
A(ii, :) = [1 2 3];
end
t2 = toc;
并且
clc; clear;
N = 100000;
A = zeros(N, 3);
t1 = tic;
for ii = (N-1):-1:2
A(ii, :) = [];
end
t2 = toc;
结果:第一个(修改预分配矩阵)为0.009s,第二个为53.429(从矩阵中删除行)。我认为这基本上解决了这个问题: NO,从矩阵中删除行/列无法使用,因为它肯定涉及深度复制数据和重新分配内存。
此外,删除列而不是行也不是一个好主意。正如我测试的那样,在上述复杂程度上,它仍然需要大约两分钟的时间:
N = 100000;
test_m = zeros(3, N);
tic
for ii = (N - 1):-1:2
test_m(:, ii) = [];
end
toc
% result: 105.436595 seconds.
% This was run on a different machine than the previous examples.
% But is still enough evidence that dynamically resizing a big matrix is a BAD idea.
所以,故事的结尾:不要试图以这种方式删除列或行,除非你有一个非常小的矩阵。对于庞大的矩阵,请始终使用预分配。
答案 0 :(得分:2)
这里有几个问题:
1)如果不使用mex,则无法控制矩阵删除是否使用相同的内存。但是,您可以判断它是否发生。一种方法是用mex编写东西。或者,您可以激活format debug
N = 100000;
test_m = zeros(3, N);
t = evalc('disp(test_m)');
disp(t(1:100))
test_m(:,2:N-1) = [];
disp(t(1:100))
这将产生输出
Structure address = 1259f6da0
m = 3
n = 100000
pr = 15d6d2020
pi = 0
Columns 1 through 9
0
Structure address = 1259f6b70
m = 3
n = 2
pr = 608001c95320
pi = 0
0 0
0 0
0
0
请注意,为了使显示合理,我捕获了显示变量的输出,然后仅显示了其中的一部分。此输出,尤其是pr
(指向实际数据的指针)指示发生了重新分配。我找不到任何未发生重新分配的情况。
2)正如某些注释中提到的和在问题中提到的那样,内存存储为以列为主。因此,当您删除列时,它可能比删除行更有效...
3)我不确定代码示例是否现实,但是一次性删除所有列或行会更有意义。这真的发生得很快。
N = 100000;
test_m = zeros(3, N);
test_m(:,2:N-1) = [];
4)最后,我不确定您的措辞指的是预分配修改还是删除。大图,最好避免在循环中删除行或列。而是保留一个数组,该数组指示应删除哪些列或行,然后一次性完成。