MATLAB Answers

Object Oriented Programming Performance Comparison: Handle Class vs. Value Class vs. no OOP

73 views (last 30 days)
Changhua Cao
Changhua Cao on 9 Sep 2011
Commented: Zhengyi on 17 May 2018
I have used Matlab for many years, but have not use the object oriented programming feature until one week ago. The first thing I noticed is that Matlab OOP style is significantly different from other OOP languages such as C++ or java. The next thing I noticed is the significant performance penalty from OOP. In some extreme case, my program slows down by more than 100X, as also reported by other users.
I did several experiments. I feel I find a way to make OOP almost as fast as traditional Matlab program. Both of the observations actually have been pointed out in previous threads. I hope if some expert can confirm this.
The following is summary of my observations.
  • do not call object's method in a loop. Calling the object methods involves a lot of overhead. A bad example is to call the object's method in a for loop.
  • do not use handle class. If it does not mess up your program too much, use value class instead.
Handle class is convenient to use, but it is too slow. Reading or writing object properties, either in object method or from external, it is more than 100X slower in handle class, as shown my test 2 to 4. Something similar to the following is more than 1000X slower in handle class
obj.b = obj.a
It is easy to understand the first one, however I am very curious about the performance difference between handle class and value class. If there is expert in this forum, could you please give some explanation on my observation?
Another question: I need to change the properties of a value class through the its method. It seems that I have to put the object as one of the return parameter, and have to call the method as the following. Is there any better way?
[obj, xout] = obj.method(xin)
Attach one: Experiment Results
Test 1: 100,000 times Method Call
======================================
handle class: Elapsed time is 3.302863 seconds.
value class: Elapsed time is 5.727677 seconds.
no oop: Elapsed time is 0.024743 seconds.
Test 2: 100,000 times Property Internal Access (i.e. in Method)
==============================================
handle class
style 1: Elapsed time is 0.022400 seconds.
style 2: Elapsed time is 0.039167 seconds.
style 3: Elapsed time is 1.780666 seconds.
style 4: Elapsed time is 0.039056 seconds.
no oop: Elapsed time is 0.000502 seconds.
value class
style 1: Elapsed time is 0.000255 seconds.
style 2: Elapsed time is 0.000522 seconds.
style 3: Elapsed time is 0.000242 seconds.
style 4: Elapsed time is 0.000398 seconds.
no oop: Elapsed time is 0.000503 seconds.
Test 3: 100,000 times Properties External Set
==============================================
handle class: Elapsed time is 0.022604 seconds.
value class: Elapsed time is 0.000223 seconds.
no oop: Elapsed time is 0.000189 seconds.
Test 4: 100,000 times Properties External Get
=============================================
handle class: Elapsed time is 0.011324 seconds.
value class: Elapsed time is 0.000221 seconds.
no oop: Elapsed time is 0.000220 seconds.
Attachment two: source code
% no oop function
function a = func_no_oop()
a = 1;
end
% handle class
classdef class_handle < handle
properties
a;
b;
end
methods
function obj = class_handle()
obj.a = 0;
obj.b = 0;
end
function assign(obj)
obj.a = 1;
end
function assignN(obj)
fprintf(1, 'style 1: ');
tic;
for ii = 1:100000
obj.a = 1;
end
toc;
fprintf(1, 'style 2: ');
tic;
for ii = 1:100000
obj.a = obj.a + 1;
end
toc;
fprintf(1, 'style 3: ');
tic;
for ii = 1:100000
obj.b = obj.a;
end
toc;
fprintf(1, 'style 4: ');
tic;
for ii = 1:100000
c = obj.a;
obj.b = c;
end
toc;
fprintf(1, 'no oop: ');
d = 1;
tic
for ii = 1:100000
d = d + 1;
end
toc
end
end
end
% value class
classdef class_value
properties
a;
b;
end
methods
function obj = class_value()
obj.a = 0;
obj.b = 0;
end
function obj = assign(obj)
obj.a = 1;
end
function obj = assignN(obj)
fprintf(1, 'style 1: ');
tic;
for ii = 1:100000
obj.a = 1;
end
toc;
fprintf(1, 'style 2: ');
tic;
for ii = 1:100000
obj.a = obj.a + 1;
end
toc;
fprintf(1, 'style 3: ');
tic;
for ii = 1:100000
obj.b = obj.a;
end
toc;
fprintf(1, 'style 4: ');
tic;
for ii = 1:100000
c = obj.a;
obj.b = c;
end
toc;
fprintf(1, 'no oop: ');
d = 1;
tic
for ii = 1:100000
d = d + 1;
end
toc
end
end
end
%Compare Script
obj_handle = class_handle();
obj_value = class_value();
disp(' ');
disp('Test 1: 100,000 times Method Call');
disp('======================================');
fprintf(1, 'handle class: ');
tic;
for ii = 1: 100000
obj_handle.assign();
end
toc;
fprintf(1, 'value class: ');
tic;
for ii = 1: 100000
obj_value.assign();
end
toc;
fprintf(1, 'no oop: ');
tic;
for ii = 1: 100000
func_no_oop();
end
toc;
disp(' ');
disp('Test 2: 100,000 times Property Internal Access');
disp('==============================================');
disp('handle class' );
obj_handle.assignN();
disp(' ');
disp('value class');
obj_value.assignN();
disp(' ');
disp('Test 3: 100,000 times Properties External Set');
disp('==============================================');
fprintf(1, 'handle class: ');
tic;
for ii = 1: 100000
obj_handle.a = 1;
end
toc;
fprintf(1, 'value class: ');
tic;
for ii = 1: 100000
obj_value.a = 1;
end
toc;
fprintf(1, 'no oop: ');
tic;
for ii = 1: 100000
a = 1;
end
toc;
disp(' ');
disp('Test 4: 100,000 times Properties External Get');
disp('=============================================');
fprintf(1, 'handle class: ');
tic;
for ii = 1: 100000
x = obj_handle.a;
end
toc;
fprintf(1, 'value class: ');
tic;
for ii = 1: 100000
x =obj_value.a;
end
toc;
fprintf(1, 'no oop: ');
tic;
for ii = 1: 100000
x = a;
end
toc;

  3 Comments

Eric Sampson
Eric Sampson on 21 May 2013
You might want to try this test again with a newer version of MATLAB, I think they've improved things in the latest version.
JMP Phillips
JMP Phillips on 16 Apr 2015
I ran this test on MATLAB R2014b, OOP is still slower than non-OOP
Test 1: 100,000 times Method Call
======================================
handle class: Elapsed time is 1.392987 seconds.
value class: Elapsed time is 2.850584 seconds.
no oop: Elapsed time is 0.035603 seconds.
Test 2: 100,000 times Property Internal Access
==============================================
handle class
style 1: Elapsed time is 0.019482 seconds.
style 2: Elapsed time is 0.028726 seconds.
style 3: Elapsed time is 0.743538 seconds.
style 4: Elapsed time is 0.028799 seconds.
no oop: Elapsed time is 0.000471 seconds.
value class
style 1: Elapsed time is 0.000255 seconds.
style 2: Elapsed time is 0.000369 seconds.
style 3: Elapsed time is 0.000265 seconds.
style 4: Elapsed time is 0.000332 seconds.
no oop: Elapsed time is 0.000346 seconds.
Test 3: 100,000 times Properties External Set
==============================================
handle class: Elapsed time is 0.019245 seconds.
value class: Elapsed time is 0.000225 seconds.
no oop: Elapsed time is 0.000230 seconds.
Test 4: 100,000 times Properties External Get
=============================================
handle class: Elapsed time is 0.008904 seconds.
value class: Elapsed time is 0.000222 seconds.
no oop: Elapsed time is 0.000224 seconds.
Ryan
Ryan on 21 Oct 2015
The following results are from Matlab 2015b, which includes a new execution engine. It appears that method call performance has improved significantly, but value class performance on set and get properties has degraded to be similar to that of handle classes.
Test 1: 100,000 times Method Call
======================================
handle class: Elapsed time is 0.146305 seconds.
value class: Elapsed time is 0.545698 seconds.
no oop: Elapsed time is 0.013126 seconds.
Test 2: 100,000 times Property Internal Access
==============================================
handle class
style 1: Elapsed time is 0.022317 seconds.
style 2: Elapsed time is 0.027134 seconds.
style 3: Elapsed time is 0.027577 seconds.
style 4: Elapsed time is 0.027205 seconds.
no oop: Elapsed time is 0.000344 seconds.
value class
style 1: Elapsed time is 0.023000 seconds.
style 2: Elapsed time is 0.028270 seconds.
style 3: Elapsed time is 0.027505 seconds.
style 4: Elapsed time is 0.027507 seconds.
no oop: Elapsed time is 0.000335 seconds.
Test 3: 100,000 times Properties External Set
==============================================
handle class: Elapsed time is 0.023108 seconds.
value class: Elapsed time is 0.022511 seconds.
no oop: Elapsed time is 0.000352 seconds.
Test 4: 100,000 times Properties External Get
=============================================
handle class: Elapsed time is 0.007931 seconds.
value class: Elapsed time is 0.009054 seconds.
no oop: Elapsed time is 0.000348 seconds.

Sign in to comment.

Accepted Answer

David Young
David Young on 9 Sep 2011
There is no way to change an object of a value class on method call, other than to return the updated object as a result, and assign it to the variable that held the old object.
This is a strength. One of the core features of MATLAB is its call-by-value semantics: with non-oop MATLAB you can never, for example, accidentally change the value of an array in one part of a program by an assignment to one of its elements in some remote part of the program. Bugs caused by such actions are one of the biggest problems, especially for beginners, in call-by-reference languages. By sticking to call-by-value, MATLAB must have saved countless thousands of hours of debugging time over the years.
However, handle classes break this, which in the context of MATLAB's normal programming model is dangerous. Therefore handle classes should, in my view, only be used when there is an overriding reason. One possible reason is to represent a unique object; another is to implement certain data structures which can only be efficiently updated with handle-class semantics.

  0 Comments

Sign in to comment.

More Answers (1)

Yingcong Zhou
Yingcong Zhou on 25 Mar 2018
Hi Guys,
I tried this code with the latest MATLAB 2018a. The CPU is Intel Core i7-4700HQ.
The result is close to MATLAB 2015b. The difference between OOP and non-OOP is reduced. Handle class and value class have similar performance.
Test 1: 100,000 times Method Call
======================================
handle class: Elapsed time is 0.049756 seconds.
value class: Elapsed time is 0.325548 seconds.
no oop: Elapsed time is 0.009795 seconds.
Test 2: 100,000 times Property Internal Access
==============================================
handle class
style 1: Elapsed time is 0.010977 seconds.
style 2: Elapsed time is 0.014852 seconds.
style 3: Elapsed time is 0.015100 seconds.
style 4: Elapsed time is 0.015547 seconds.
no oop: Elapsed time is 0.000152 seconds.
value class
style 1: Elapsed time is 0.011130 seconds.
style 2: Elapsed time is 0.015040 seconds.
style 3: Elapsed time is 0.015073 seconds.
style 4: Elapsed time is 0.015410 seconds.
no oop: Elapsed time is 0.000146 seconds.
Test 3: 100,000 times Properties External Set
==============================================
handle class: Elapsed time is 0.011074 seconds.
value class: Elapsed time is 0.010977 seconds.
no oop: Elapsed time is 0.000136 seconds.
Test 4: 100,000 times Properties External Get
=============================================
handle class: Elapsed time is 0.008371 seconds.
value class: Elapsed time is 0.008426 seconds.
no oop: Elapsed time is 0.000144 seconds.

Community Treasure Hunt

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

Start Hunting!