How does copy-on-modify operate on structs and classes?

I understand that Matlab uses "copy-on-modify" so matrices, structs and class objects are only copied inside a function when the item passed in is modified.
Question: When matlab modifies a member of a struct or class in a function, is the entire struct or class object copied, or only the member which was modified?
Why is this important? Because if a struct or class has some very large matrices embedded, then a function which modifies a small part of the entire object would either copy/modify only the small part it works with (good!), or it might duplicate the entire object, even if it only works with a small piece (bad!).
A somewhat trivial example:
s.owner="charlie";
s.data=rand(10000,10000);
s=change_owner(s,"charlene");
. . .
function t = change_owner(t,new_owner);
t.owner = new_owner;
end
If change_owner(...) sees the entire object as modified, then it has to duplicate the nearly 1 GB data matrix, in order to change the owner field, which makes this function very inefficient. But if matlab recognizes that only the "owner" member is modified, then it can avoid duplicating the data matrix, and thus operate efficiently on the struct.
The same question obviously would apply to a class object as to a struct...

 Risposta accettata

James Tursa
James Tursa il 29 Apr 2019
Modificato: James Tursa il 29 Apr 2019
Question: When matlab modifies a member of a struct or class in a function, is the entire struct or class object copied, or only the member which was modified?
Only the member being modified is deep copied. The other members are typically reference copied only. E.g., in the following you can see that the data pointer value pr did not change ... i.e. the memory of the data field was not deep copied.
>> s.owner = 'charlie';
>> s.data = rand(1,5);
>> format debug
>> s.data
ans =
Structure address = 54747f90
m = 1
n = 5
pr = 11c661dc0
pi = 0
0.8147 0.9058 0.1270 0.9134 0.6324
>> s = change_owner(s,'charlene')
s =
owner: 'charlene'
data: [0.8147 0.9058 0.1270 0.9134 0.6324]
>> s.data
ans =
Structure address = 54747f90
m = 1
n = 5
pr = 11c661dc0
pi = 0
0.8147 0.9058 0.1270 0.9134 0.6324

4 Commenti

Ian
Ian il 29 Apr 2019
Modificato: Ian il 30 Apr 2019
great. thx.
"format debug" is a new one on me. Thanks for the example.
For anyone else who reads this thread: A little googling turned up the following interesting links on memory management, parameter passing, copy-on-write and "format debug" (which appears to be an undocumented Matlab feature AFAICT).
First, Loren's (2006) post regarding Matlab's memory management has some helpful info both in her explanation and in the comments
Second, some very insightful examples demonstrated by the use of "format debug" are in the links found at
Curious...when I turn on format debug, I don't get info on the imaginary pointer, in either R2018b or R2019a, even when I explicity make data complex or purely imaginary:
>> version
ans =
'9.6.0.1072779 (R2019a)'
>> format debug
>> s.data='charlie'; s.data=rand(1,3);
>> s.data
ans =
Structure address = 13feab970
m = 1
n = 3
pr = 600004a7b3e0
0.4854 0.8003 0.1419
>> s.data=s.data + i*rand(1,3)
s =
struct with fields:
owner: 'charlie'
data: [0.4854 + 0.4218i 0.8003 + 0.9157i 0.1419 + 0.7922i]
>> s.data
ans =
Structure address = 13fea2e10
m = 1
n = 3
pr = 6040020849e0
0.4854 + 0.4218i 0.8003 + 0.9157i 0.1419 + 0.7922i
>> s.data = i*rand(1,3);
>> s.data
ans =
Structure address = 13fe9bf90
m = 1
n = 3
pr = 60000309ad80
0.0000 + 0.9595i 0.0000 + 0.6557i 0.0000 + 0.0357i
MATLAB stores interleave complex numbers starting from R2018b. So there is no longer Pi pointer.
Ah. Thnx.
I learn something new every day...

Accedi per commentare.

Più risposte (0)

Richiesto:

Ian
il 29 Apr 2019

Commentato:

Ian
il 30 Apr 2019

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by