From: Andy on 29 Jul 2010 14:29 Caveat: I am very new to OOP, both in MATLAB and in general. I've been seeing some weird memory usage. For example: % saved as myClass.m classdef myClass properties prop1 = 0; prop2 = 0; prop3 = []; prop4 = []; prop5 = 0; end end % at the command line: >> a=myClass; >> b=[0 0]; >> c=[]; >> d.field1 = 0; d.field2 = 0; d.field3 = []; d.field4 = []; >> whos Name Size Bytes Class Attributes a 1x1 120 myClass b 1x2 16 double c 0x0 0 double d 1x1 720 struct It was surprising to me that the struct was so much worse than the class, each storing the same amount of data. It was not as surprising that the class takes significantly more space than storing two zeros and two empty matrices. But the following was really weird: >> e=psAgency; >> whos Name Size Bytes Class Attributes a 1x1 120 myClass b 1x2 16 double c 0x0 0 double d 1x1 720 struct e 1x1 112 psAgency I don't want to go into the details of psAgency (it's a class I'm in the process of creating for work). But it's similar to the following: classdef psAgency properties prop1 = 0; prop2 = 0; %... prop12 = 0; prop13 = []; prop14 = []; prop15 = []; end methods function obj = psAgency(varargin) p=inputParser; p.addParamValue('prop1',0,@(x) isnumeric(x)); %... p.addParamValue('prop12',0,@(x) isnumeric(x)); p.addParamValue('prop13',[],@(x) isa(x,'myClass1')); p.addParamValue('prop14',[],@(x) isa(x,'myClass1')); p.addParamValue('prop15',[],@(x) isa(x,'myClass2')); p.parse; obj.prop1 = p.Results.prop1; %... obj.prop15 = p.Results.prop15; end end end So it stores much more data than myClass, but takes up less space?
From: Matt J on 29 Jul 2010 15:28 "Andy " <myfakeemailaddress(a)gmail.com> wrote in message <i2sha5$ct2$1(a)fred.mathworks.com>... > It was surprising to me that the struct was so much worse than the class, each storing the same amount of data. ============= The difference, I suspect, is that data related to class defintion (names of properties, functions, etc...) are not accounted for in whos(). Class definition data is loaded into MATLAB only once and MATLAB knows that these will be unchanging throughout the session unless "clear classes" is issued. So, a decision was probably made that whos() would account for class instance data only. Structures, however, have field names that are changeable throughout a MATLAB session and so whos() would want to keep track of the memory allocated to those, in addition to data. > But the following was really weird: > I don't want to go into the details of psAgency (it's a class I'm in the process of creating for work). But it's similar to the following: > > classdef psAgency > properties > prop1 = 0; > prop2 = 0; > %... > prop12 = 0; > prop13 = []; > prop14 = []; > prop15 = []; > end > > So it stores much more data than myClass, but takes up less space? =========== It's because most of your extra properties contain [] initial values. Repeated instances of [] require no extra memory to store, or at least not as far as whos() is concerned. You can test this by adding more class properties with []. You will see that the output of whos is unchanged.
From: Andy on 29 Jul 2010 15:44 First, a typo in the OP: % saved as myClass.m classdef myClass properties prop1 = 0; prop2 = 0; prop3 = []; prop4 = []; % there is no prop5 end end The class vs. structure makes sense. I hadn't thought about the need to store the field names for each instance of the structure. But the myClass vs. psAgency still doesn't make sense to me. Note that not all extra properties are []. myClass (initiated without arguments) stores two 0's and two []'s, while psAgency (initiated without arguments) stores twelve 0's and three []'s. Even though the []'s don't actually take up memory, I would think the number of 0's stored should have made a psAgency object use more memory than a myClass object.
From: Matt J on 29 Jul 2010 16:17 "Andy " <myfakeemailaddress(a)gmail.com> wrote in message <i2slm4$3pk$1(a)fred.mathworks.com>... > The class vs. structure makes sense. I hadn't thought about the need to store the field names for each instance of the structure. ============= Not really for each instance. The following operation should not result in any copying of the field names of Structure1, for example. There will be new memory allocated for the Structure2.somefield data only. Structure2=Structure1 Structure2.somefield=rand(1); On the other hand, whos() will still report memory stats as though the field names were copied, even when they are not. > But the myClass vs. psAgency still doesn't make sense to me. Note that not all extra properties are []. myClass (initiated without arguments) stores two 0's and two []'s, while psAgency (initiated without arguments) stores twelve 0's and three []'s. Even though the []'s don't actually take up memory, I would think the number of 0's stored should have made a psAgency object use more memory than a myClass object. ================ I can't reproduce what you're seeing. Here's what I get >> clear classes; a=myClass; e=psAgency; whos Name Size Bytes Class Attributes a 1x1 72 myClass e 1x1 152 psAgency So, psAgency is consuming significantly more memory for me. One thing you should keep in mind, though, is that psAgency has a constructor defined for it, unlike myClass, and that constructor gets called with no arguments, possibly resulting in changes to the initial data. You need to be careful of that in your comparisons.
From: Andy on 29 Jul 2010 16:44
I think I figured it out. psAgency had been a subclass of handle. I thought I had deleted that, but apparently MATLAB hadn't reloaded the new class definition. The following should show the difference: classdef myClass properties prop1 = 0; prop2 = 0; prop3 = 0; prop4 = 0; prop5 = 0; prop6 = 0; prop7 = 0; prop8 = 0; prop9 = 0; prop10 = 0; prop11 = 0; prop12 = 0; prop13 = 0; prop14 = 0; prop15 = 0; end methods function obj = psAgency(varargin) p=inputParser; p.addParamValue('prop1',0,@(x) isnumeric(x)); p.addParamValue('prop2',0,@(x) isnumeric(x)); p.addParamValue('prop3',0,@(x) isnumeric(x)); p.addParamValue('prop4',0,@(x) isnumeric(x)); p.addParamValue('prop5',0,@(x) isnumeric(x)); p.addParamValue('prop6',0,@(x) isnumeric(x)); p.addParamValue('prop7',0,@(x) isnumeric(x)); p.addParamValue('prop8',0,@(x) isnumeric(x)); p.addParamValue('prop9',0,@(x) isnumeric(x)); p.addParamValue('prop10',0,@(x) isnumeric(x)); p.addParamValue('prop11',0,@(x) isnumeric(x)); p.addParamValue('prop12',0,@(x) isnumeric(x)); p.addParamValue('prop13',0,@(x) isnumeric(x)); p.addParamValue('prop14',0,@(x) isnumeric(x)); p.addParamValue('prop15',0,@(x) isnumeric(x)); p.parse(varargin{:}); obj.prop1 = p.Results.prop1; obj.prop2 = p.Results.prop2; obj.prop3 = p.Results.prop3; obj.prop4 = p.Results.prop4; obj.prop5 = p.Results.prop5; obj.prop6 = p.Results.prop6; obj.prop7 = p.Results.prop7; obj.prop8 = p.Results.prop8; obj.prop9 = p.Results.prop9; obj.prop10 = p.Results.prop10; obj.prop11 = p.Results.prop11; obj.prop12 = p.Results.prop12; obj.prop13 = p.Results.prop13; obj.prop14 = p.Results.prop14; obj.prop15 = p.Results.prop15; end end end Define myClass2 exactly the same way, but with: classdef myClass2 < handle %... Then: a=myClass; b=myClass2; whos Name Size Bytes Class Attributes a 1x1 224 myClass b 1x1 112 myClass2 I still don't quite understand this. I don't see how the instance of myClass2 can store less than 15 doubles, which ought to take 120 bytes. |