This function here is eating a lot of time in my run. But what is see is the most of the time goes in the inbuilt function polyarea. Can this code be vectorized for performance boost?
Profiler Report –
time calls
1 function [S S_area] = Polygons_intersection_Compute_area(S)
2 % Guillaume JACQUENOT
3 % guillaume at jacquenot at gmail dot com
4 % 2007_10_08
5 % 2009_06_16
6 % Compute area of each polygon of in S.
7 % Results are stored as a field in S
8
0.50 51945 9 S_area = struct('A', {});
0.20 51945 10 for i=1:numel(S)
0.28 103890 11 S(i).area = 0;
1.34 103890 12 S_area(i).A = zeros(1,numel(S(i).P));
0.69 103890 13 for j=1:numel(S(i).P)
9.24 103890 14 S_area(i).A(j) = polyarea(S(i).P(j).x,S(i).P(j).y);
0.28 103890 15 S(i).area = S(i).area + (1-2*S(i).P(j).hole) * S_area(i).A(j);
0.01 103890 16 end
0.08 103890 17 end
I see 4 issues. I’ll discuss them in increasing order of potential performance gain.
First: you use
iandjas loop variable names. These are also the names of the imaginary unit in Matlab, which means Matlab will have to spend some time looking up which one you mean. Thing is, it has to do that on each iteration if the loop is not JIT’ed (which yours isn’t, I’ll get to that).Second: indexing multi-dimensional structures takes more time than you think. Multi-D structures are somewhat notorious in this respect, and you had better avoid too many indexing operations on them. Often making a simple copy of an element, doing all your operations on that copy, and then writing the copy back to the structure can increase performance quite a bit.
Third: you don’t pre-allocate
S_areain the most efficient way. You don’t even pre-allocate the structure, but grow it in the first loop when you pre-allocateS_area(i).A. This can all be improved (see below).Fourth:
polyareais not a built-in function, and so this double-loop will not be JIT’ed. If you call any function inside a loop that either you or the Mathworks wrote in M-language (rather than C), the JIT compiler will be unable to compile your loop. This is by far the most annoying (and improvable) limitation in the JIT framework, while JIT’ed loops can often run a factor of 100 or more faster than non-JIT’ed loops.The only solution often is to “inline” a non-builtin function in the loop body. In Matlab that means: copy-paste the entire contents of the function body into the loop, and do this recursively for all non-builtin functions called in that body.
All of the above leads to this version of your code:
I could not test this as properly as you can, so if you find some errors, please let me know and I’ll try to correct them.