How to optimize this code to run faster?
Show older comments
Hello,
I have a code that is attached that I am trying to optimize in order for it to run faster.
It contains a lot of for loops (which are very slow, I know). In the beginning this was the only way for me to code this as a beginner.
This is a small part of my original code, but it lacks in speed when I analyze it in MATLAB. It is very very slow, especially when I work with a large 3D set of images.
Can anyone help me with this, on how to optimize it. I would really appreciate it.
Thanks in advance!
Answers (1)
Adam Danz
on 18 Aug 2018
Your variable names induce anxiety in me :D
I'll tidy up the first for-loop so you can see how that's done.
I assume ndims(M) == 3 (ie, 'M' is 3D array)
If that's the case, 'Mmat' is a matrix and 'min1' is a column vector and
for ij1=1:numImages
Mmin1(:,ij1)=Mmat(:,ij1)-min1(ij1,:);
end
can be replaced by
Mmin1 = Mmat - min1';
This works because the number of columns in Mmat equals the number of columns in min1' (transposed).
You could test that these two methods produced the same results by performing both of them and storing the results under different variable names. Then use isequal()
isequal(Mmin1, Mmin1_b)
Most of your for-loops follow similar logic so why don't you give it a shot and follow-up with specific areas where you got stuck, stating what you tried, etc.
12 Comments
Mario
on 18 Aug 2018
Walter Roberson
on 18 Aug 2018
bsxfun is a good solution to that.
Starting from R2016b, MATLAB would automatically detect the situation on a plain subtraction, and would automatically operate like bsxfun (though sometimes a little slower than bsxfun.)
Mario
on 18 Aug 2018
Walter Roberson
on 18 Aug 2018
reshape() is one of the very fastest MATLAB operations. reshape() does not copy data at all: it keeps the exact same internal pointer to data but creates a new header for it with the new size, and increments the "in use" count for the data block.
That said, you do not need to use a loop for that code: provided you are using all of M1, then the code can be just
M2 = reshape(m1, XSize, YSize, []);
Mario
on 18 Aug 2018
Walter Roberson
on 18 Aug 2018
I do not think you are going to be able to do much better than looping with regionprops there, due to the need to identify isolated regions and find the centroid of each.
You are passing in the bw array to regionprops to identify regions, but because you are using logical values, regionprops detects regions out of the bw values: if you had passed in a double array then all of the 1 values together would have been treated as a single image, where with logical it means that the regions have to be located first.
The one thing you can do is preallocate:
s(numImages) = struct('Centroid',[],'WeightedCentroid',[]);
This prevents strCentroids having to grow inside the loop like you are doing now.
Mario
on 18 Aug 2018
Walter Roberson
on 18 Aug 2018
jj(ij8).PixelValues = {ji().PixelValues}.';
jj(ij8).PixelValues =cell2table(jj(ij8).PixelValues);
jj(ij8).PixelValues =table2struct(jj(ij8).PixelValues);
could be replaced with
jj(ij8).PixelValues = struct('Var1', {ji.PixelValues}.');
and
jj(ij8).BoundingBox = [ji.BoundingBox];
jj(ij8).BoundingBox=reshape(jj(ij8).BoundingBox, 4, []);
jj(ij8).BoundingBox=transpose(jj(ij8).BoundingBox);
can be replaced with
jj(ij8).BoundingBox = vertcat(ji.BoundingBox);
It is not clear to me why you have a nested for loop on iji8 that continually overwrites jj(:).PixelList .
Mario
on 18 Aug 2018
Adam Danz
on 19 Aug 2018
Wow, Walter helped you out a lot! I'll chip in two more examples.
numPix=zeros(numImages,1);
for ii=1:numImages
numPix(ii) = numel(jj(ii).PixelValues);
end
can be replaced by
numPix = cellfun(@numel, {jj.PixelValues}');
As for
numPixix=table(numPix);
numPixx=table2cell(numPixix);
for qq=1:ii
numPixxx{qq, 1}=[1:(numPixx{qq, 1})]';
end
assuming numPix is a vector (double, integers), it's replacement would be
numPixxx = cellfun(@(x)1:x, num2cell(numPix), 'UniformOutput', false);
Given the tools you learned from Walter and from these two examples, why don't you try the rest on your own. Google and this forum are great primary resources when getting stuck. If you've tried several methods and can't understand why they aren't working, follow-up here and include the methods you've tried so we can help set things straight.
Mario
on 20 Aug 2018
Categories
Find more on Loops and Conditional Statements 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!