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

 採用された回答

James Tursa
James Tursa 2019 年 4 月 29 日
編集済み: James Tursa 2019 年 4 月 29 日

3 投票

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 件のコメント

Ian
Ian 2019 年 4 月 29 日
編集済み: Ian 2019 年 4 月 30 日
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
Ian
Ian 2019 年 4 月 30 日
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
Bruno Luong
Bruno Luong 2019 年 4 月 30 日
MATLAB stores interleave complex numbers starting from R2018b. So there is no longer Pi pointer.
Ian
Ian 2019 年 4 月 30 日
Ah. Thnx.
I learn something new every day...

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeStructures についてさらに検索

質問済み:

Ian
2019 年 4 月 29 日

コメント済み:

Ian
2019 年 4 月 30 日

Community Treasure Hunt

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

Start Hunting!

Translated by