Loren on the Art of MATLAB

Turn ideas into MATLAB

Note

Loren on the Art of MATLAB has been archived and will not be updated.

Memory Management for Functions and Variables

People have different ideas about what costs a lot, in terms of memory, in MATLAB. And sometimes people don't know the details. Today I am going to talk about when MATLAB makes copies of data, for both calling functions, and for data stored in variables. MATLAB makes copies of arrays it passes only when the data referred to changes (this is called copy on write or lazy copying).

Contents

Passing Arrays to Functions

The question is, when does MATLAB copy memory when passing arrays to functions. Some users think that because MATLAB behaves as if data are passed by value (as opposed to by reference), that MATLAB always makes copies of the inputs when calling a function. This is not necessarily true. Take a look at this function.

type fred1
function y = foo(x,a,b) 
a(1) = a(1) + 12; 
y = a * x + b;

In fred1, the first and third inputs, x and b, are not altered inside. MATLAB recognizes this and passes both these variables in without making any extra copies. This can be a big memory savings, for example, if x is a large dataset. However, in fred1, we can see that the second input, a, gets modified inside. MATLAB recognizes when this is happening to a variable and makes a copy of it to work with so that the original variable in the calling workspace is not modified.

Structures and Memory

Each structure member is treated as a separate array in MATLAB. This means that if you modify one member of a structure, the other members, which are unchanged, are not copied. It's time for an illustration here.

Create some rgb image data with 3 planes: red, green, and blue.

im1.r = rand(300,300);
im1.g = rand(300,300);
im1.b = rand(300,300);

Instead, rearrange the same data so that we have an array of structs each element containing an [r g b]-triplet.

im2(300,300).rgb = [0 0 0];  % preallocate the array
for r = 1:300
    for c = 1:300
        im2(r,c).rgb = [im1.r(r,c) im1.g(r,c) im1.b(r,c)];
    end
end

Let’s compare im1 and im2.

clear c r  % tidy up the workspace
whos
  Name       Size                    Bytes  Class

  im1        1x1                   2160372  struct array
  im2      300x300                 7560064  struct array
  s          1x1                       392  struct array
  sNew       1x1                       392  struct array

Grand total is 630043 elements using 9721220 bytes

im1 is a scalar structure with members that hold m x n arrays.

  • im1.r = imageRedPlane --- size m x n
  • im1.g = imageGreenPlane --- size m x n
  • im1.b = imageBluePlane --- size m x n

im1 is size 1 x 1; total # of arrays inside im1: 3

im2 is an m x n structure array with fields containing 3-element vectors.

  • im2(i,j).rgb = imageOneRGBPixel --- size 1 x 3

im2 is size m x n; total # of arrays inside im2: m x n

Notes: Every MATLAB array allocates a header with information. This makes im1 more memory-efficient than im2 (more generally, scalar structs containing arrays are more memory-efficient than a struct array). When one field in a structure is changed, and possibly copied, the other fields are left intact.

s.A = rand(3);
s.B = magic(3);
sNew = s;
sNew.A(3) = 14;

Since s and sNew have unaltered copies of B, the B fields share memory, but the A fields do not. See the documentation section titled Using Memory Efficiently for more information.

What's Your Mental Model for MATLAB Memory Management?

Say that three times fast!

Does the description here and/or in the documentation change your model?

Let me know.


Published with MATLAB® 7.2


  • print

Comments

To leave a comment, please click here to sign in to your MathWorks Account or create a new one.