Improve speed of execution by pre allocation of array

조회 수: 2 (최근 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.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Matrices and Arrays에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by