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).
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.
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.
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.
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.
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