Search code examples
matlabprofiler

Access matrix element in condition


I'm trying to reduce the computational time of my MatLab code. For this I use the MatLab profiler.

In some functions I was in the same situation. I loop over a grid (a 2D matrix) and I test if each cell has (or not) some values (two each time). And the condition takes a long time. Most of the time spends in those functions.

Here is an example from my code:

  time      Calls    line
                      16   function tGrid=some_compute(grid, tGrid, trans)
  0.005       125     17     global depth width tWidth 
                      18
< 0.001       125     19     for i=1:depth 
  0.022    125000     20       for j=1:width 
  2.270  37500000     21         if (grid(i, j)~=0 && grid(i, j)~=1) 
                      22
                      23           % Get the transformed coordinates of the current cell
  0.864     79997     24           [x, y]=get_trans(trans, i, j); 
                      25
  0.006     79997     26           if (x~=-1 && y~=-1) 
  0.006     79992     27             tGrid(x, y)=grid(i, j); 
  0.004     79992     28           end % If x~=-1 && y~=-1 
  0.004     79997     29         end % If grid~=0 && grid~=1 
  1.933  37500000     30       end % For j=width 
  0.008    125000     31     end % For i=depth 
                      32
< 0.001       125     33   end

This function takes a total of 5.24s for 125 calls.

As we can see, it's the line 21 who take the more time to execute. While the the grid(i, j) is accessed twice in the condition, and is also used in line 27, I guessed by storing it in a variable before, it will speed-up my code.

So, I did this simple modification:

  time      Calls    line
                      16   function tGrid=some_compute(grid, tGrid, trans)
  0.005       125     17     global depth width tWidth
                      18
< 0.001       125     19     for i=1:depth
  0.021    125000     20       for j=1:width
  2.062  37500000     21         val=grid(i, j);
  1.681  37500000     22         if (val~=0 && val~=1)
                      23
                      24           % Get the transformed coordinates of the current cell
  0.793     79997     25           [x, y]=get_trans(trans, i, j);
                      26
  0.005     79997     27           if (x~=-1 && y~=-1)
  0.005     79992     28             tGrid(x, y)=val;
  0.004     79992     29           end % If x~=-1 && y~=-1
  0.004     79997     30         end % If grid~=0 && grid~=1
  1.731  37500000     31       end % For j=width
  0.007    125000     32     end % For i=depth
                      33
< 0.001       125     34   end

And now, this function takes a total of 6.32s for 125 calls.

As we can see, getting the value of the cell take as much time as getting it twice and compare it to two values. And the if, line 22, is as much slow as in the first version. I don't understand why.


Solution

  • getting the value of the cell take as much time as getting it twice and compare it to two values. [...] I don't understand why.

    This is because your code is run under a JIT (just-in-time compiler). This compiler optimizes your code. Though it's not documented how exactly it works and what kind of optimizations are implemented, from your experiment it seems clear that grid(i, j)~=0 && grid(i, j)~=1 is optimized to only fetch the value grid(i,j) once.