Are handle classes the fastest containers?

41 次查看(过去 30 天)
I was starting to familiarize myself with the differences between structs, value classes and handle classes, as well as with the optimizations MATLAB performs to avoid unnecessary copying of data.
I wrote a small sample program that tests the time it takes to pass these different data containers (structs, value classes, handle classes), filled with a large matrix, as arguments to a function, and I did that for a read, write and write&reassign function. These were the results (partially as expected, partially not):
  • Reading is equally fast for structs, value classes and handle classes, as MATLAB's optimization avoids copying the data
  • Writing is slow for structs and value classes, as MATLAB copies the data, while handle classes are faster as they explicitly don't make copies. Of course, the faster behaviour of handle classes isn't a fair comparison here, as the results of the writing differ wrt the case of structs and value classes.
  • Writing&reassigning is equally fast for all of them, yet much slower then reading.
BUT:
  • When writing or writing&reassigning, functions that are given handle class arguments show a large performance leap from the second time these functions are called: writing suddenly becomes as fast as reading, which is a speedup of about a factor 1000-10000.
I can't explain this. If this has something to do with the just-in-time compilation, why is the behaviour different for handle classes wrt value classes or structures?
Here is a sample of the observed timings for the different cases. The full script + output can be found here: https://gist.github.com/asparc/c6597c70b43a493cca1428af77f9304c
Read
====
struct: 0.001657
struct: 0.000061
class: 0.001487
class: 0.000059
handle: 0.001249
handle: 0.000055
Write
=====
struct: 2.339701
struct: 2.372296
class: 2.333061
class: 2.352433
handle: 0.425259
handle: 0.000089
Write & re-assign
=================
struct: 0.419934
struct: 0.412815
class: 0.414880
class: 0.411838
handle: 0.000737
handle: 0.000062

采纳的回答

Bruno Luong
Bruno Luong 2020-10-30
编辑:Bruno Luong 2020-10-30
I did not run your code, just read through but I believe you run into the fact that MATLAB makes cdata opy when you change an element only when same whole data are shared by 2 or more variables.
A = rand(10000);
B = A; % no copy, but data are now shared
B(1) = 1; % copy, data are separate between A and B
B(1) = 2; % no copy, since data no longer shared, MATLAB make inplace change
That explains the behaviour you see and handle class and the data is unique.
For other container, because of the function you put around, and variable are used in LHS on both RHS, MATLAB CANNOT assume whereas the LSH is the same as RHS, so it copies systematically the arrays.
Also your timining is flawed by the fact that you call function and use global statement. The overhead of those will introduce bias in yout time. Personally I never time something small but putting them in a function.
Never put small instructions in a function with MATLAB, it will kill the performance.
  1 个评论
Caspar Gruijthuijsen
What you are saying about the copy vs inplace change makes a lot of sense and indeed explains my observations. I didn't know about this behaviour! Thank you for clarifying!

请先登录,再进行评论。

更多回答(1 个)

Ameer Hamza
Ameer Hamza 2020-10-30
编辑:Ameer Hamza 2020-10-30
There is a performance overhead for using handle classes if you try to access its properties repeatedly. This thread summarizes it: https://www.mathworks.com/matlabcentral/answers/15533-object-oriented-programming-performance-comparison-handle-class-vs-value-class-vs-no-oop. However, from your question description, it seems that you are manipulating a large matrix, in which case you might not need to access them repeatedly, which explain faster performance using handle classes.
Following links are also useful:

类别

Help CenterFile Exchange 中查找有关 Structures 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by