필터 지우기
필터 지우기

Preallocating for speed, what kind of variable is this?

조회 수: 2 (최근 30일)
Recap
Recap 2016년 3월 26일
편집: dpb 2016년 3월 27일
I'm looking through some code and I came across this loop where Box should be preallocated for speed. Box, is the variable that I should preallocate outside the loop. But I don't know what kind of a variable it is. Can anyone help by looking at this?
for posi = 1:Length
nArea=nBox(posi).Area; % Area of number/letters
nBox(posi).BoundingBox; % Frame objects
if nArea>50 && nArea<200 && ...
nBox(posi).BoundingBox(4)>10 && nBox(posi).BoundingBox(3)>7 && ...
nBox(posi).BoundingBox(3)<25
k=k+1;
Box(k,:)=round(nBox(posi).BoundingBox);
end
end

채택된 답변

dpb
dpb 2016년 3월 26일
편집: dpb 2016년 3월 27일
Box is just a 2D array of type whatever is nBox.BoundingBox (which would appear to be a floating point type given the round operation, else't it's a waste).
As for preallocating, the size isn't known a priori; only the number of rows that satisfy the condition will be allocated. Depending on the matnitude of the upper bound of the loop Length, the time savings may be trivial compared to the overhead of allocating a set, checking for overrunning and reallocating, etc., etc., etc., ...
You could, of course, allocate for the full Length rows and clear k+1:end after the loop finishes. The 2nd dimension is whatever is the size of the structure array.
It appears that the loop could be replaced if this is all there is by --
idx= isbetween(nBox.nArea,50,200) & ...
isbetween(nBox.BoundingBox(3),7,25) & ...
nBox.BoundingBox(4)>10;
Box=round(nBox(idx).BoundingBox);
where isbetween is my "syntactic sugar" utility function
>> type isbetwween
function flg=isbetween(x,lo,hi)
% returns T for values within range of input
% SYNTAX:
% [log] = iswithin(x,lo,hi)
% returns T for x between lo and hi values, exclusive
flg= (x>lo) & (x<hi);
>>
I've several of these that serve simply to reduce clutter at the upper level; another is iswithin which is inclusive on both bounds.
NB: The statement
nBox(posi).BoundingBox; % Frame objects
is pointless; perhaps it was a debug line if removed the trailing semi-colon to echo the values during development.
ERRATUM
As Guillaume reminds me, since LHS is an array instead of reduced structure arrray must contatenate the results--
Box=round(cat(1,nBox(idx).BoundingBox));
  댓글 수: 2
Recap
Recap 2016년 3월 26일
The range of Length will vary from 3 to 8. So is there no way to preallocate the Box since it will vary everytime?
dpb
dpb 2016년 3월 26일
Well, yes, you can allocate Length elements but for only 8 max you'll not notice the difference unless this is buried deep in some nested construct.
But, as noted, throw away the loop and it'll all get allocated in "one swell foop" from the git-go and preallocating is then a non-issue.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Guillaume
Guillaume 2016년 3월 26일
편집: Guillaume 2016년 3월 26일
As per dpb's answer, the loop and the if are completely unnecessary (and slow). Just use logical indexing on the whole array. As a result Box gets created in one go, when it receives the values and therefore there's no need to preallocate (as it would just slow down the code).
Now, dpb's answer is incorrect in the assignment to Box, but he's got the right idea. This will work:
areas = [nBox.Area];
bboxes = vertcat(nBox.BoundingBox);
Box = round(bboxes(areas > 50 & areas < 200 & bboxes(:, 4) > 10 ...
& bboxes(:, 3) > 7 & bboxes(:, 3) < 25, :));
Note that a comment explaining why the bounding box coordinates are rounded wouldn't go amiss. Assuming the coordinates come from regionprop, ceil would be more appropriate.
  댓글 수: 3
Guillaume
Guillaume 2016년 3월 26일
Only in missing a closing parenthesis
Not really. nBox is a structure array. So you've got to cat nbox.Area and nbox.BoundingBox.
dpb
dpb 2016년 3월 27일
Hmmm...oy, yeah...forgotted it being an array as the target instead of a reduced structure array. OK, so I fixed that, too... :)

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Matrix Indexing에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by