Improve speed of execution by pre allocation of array

1 ビュー (過去 30 日間)
Askic V
Askic V 2022 年 9 月 8 日
編集済み: Askic V 2022 年 9 月 9 日
Hello,
I know that changing size of an array in each loop iteration is not only a bad practice but also a very inefficient way to do things.
But there are cases, where it is not possible to know the exact siye of an array in advance and the size can significantly vary depending on different condtions inside the loop.
For example, I have the following code:
A = randi([-10 10], 1, 100000);
B = [];
for i = 1:length(A)
if A(i) > 5 || A(i) < 2
B = [B A(i)]
end
end
How preallocation could be done in this and similar case?
The other idea is to use find function to find indices of values in A according to the certain criteria, and then to allocate B based on the size of this indices array obtained in the previous step.
Something like this:
ind1 = find(A>5);
ind2 = find(A<2);
B = zeros(1, length(ind1)+length(ind2));
ind = sort([ind1 ind2]);
for i = 1:length(ind)
B(i) = A(ind(i));
end

採用された回答

Stephen23
Stephen23 2022 年 9 月 8 日
編集済み: Stephen23 2022 年 9 月 8 日
"How preallocation could be done in this and similar case?"
In that and similar cases the MATLAB approach would be to simply assign to a basic logical index (not subscript indexing like you were doing using FIND), and then do the entire indexing once after the loop:
N = 100000;
A = randi([-10,10],1,N);
X = false(1,N); % preallocate logical index
for k = 1:N
X(k) = A(k)>5 || A(k)<2; % no array expansion here.
end
B = A(X); % indexing after the loop
Of course this simpe example would be even better without the loop, again using basic logical indexing:
X = A>5 || A<2;
B = A(X);
In actual situations where it is not possible to know the size of an array in advance you have several basic approaches:
  • preallocate an array large enough for all data, then trim the array once after the loop. This works well if the maximum possible size is possible to predict, and if that size can fit comfortably in memory.
  • increase the array size in large blocks when required, e.g. 1e4 rows at a time. This is a bit more fiddly to write code for, but does reduce how often the array is moved in memory. Be prepared to do quite a bit of unit testing and tuning to get this right.
  1 件のコメント
Askic V
Askic V 2022 年 9 月 8 日
Thank you for the very detailed explanation.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Find more on Resizing and Reshaping Matrices in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by