Graphic handle properties
There are several ways to access (read or update) Handle Graphics object properties. The simplest (and documented) way is to use the built-in get and set functions on the HG object’s handle. However, it is not the fastest: a significant speedup is possible (see below).
Accessing individual properties is so fast that this speedup may not seem important. Individual properties are accessed in tens or hundreds of microseconds, which is a very short time for most Matlab programs. Indeed, if our application seldom accesses properties, it is probably not worth the effort to optimize this particular aspect of the program:
% Individual property access is extremely fast: hFig = figure; tic, figName = get(hFig,'name'); toc % Elapsed time is 0.000229 seconds. tic, set(hFig,'name','testing'); toc % Elapsed time is 0.000270 seconds.
But if we have thousands of reads and/or updates, this could possibly become an important factor (drawnow calls are intentionally omitted to illustrate the effect):
% Using the standard set() function tic, for idx=1:10000, set(hFig,'name','testing'); end, toc % Elapsed time is 0.229772 seconds. % Using the HG handle() wrapper is about 25% faster (or 1.3x speedup): tic hFig = handle(hFig); for idx=1:10000, set(hFig,'name','testing'); end toc % Elapsed time is 0.170205 seconds. % Using the HG handle() wrapper with dot notation is even faster (65% faster, or 2.7x speedup): tic hFig = handle(hFig); for idx=1:10000, hFig.name='testing'; end toc % Elapsed time is 0.083762 seconds.
Similar results occur when trying to get() a property value:
% Using the standard set() function tic, for idx=1:10000, s=get(hFig,'name'); end, toc % Elapsed time is 0.140865 seconds. % Using the HG handle() wrapper is about 25% faster (or 1.3x speedup): tic, hFig=handle(hFig); for idx=1:10000, s=get(hFig,'name'); end, toc % Elapsed time is 0.108543 seconds. % Using the HG handle() wrapper with dot notation is even faster (62% faster, or 2.6x speedup): tic, hFig=handle(hFig); for idx=1:10000, s=hFig.name; end, toc % Elapsed time is 0.053423 seconds.
We learn from this that using the HG handle() wrapper function is useful for improving performance. This has the benefit of improving our code performance with minimal changes to our code, by simply updating our handle to be a handle() wrapper:
hFig = handle(hFig);
Using the handle’d handle enables further performance benefits if we use the dot notation (handle.propertyName
), rather than use the familiar get/set functions.
Note that both the handle function and its beneficial effects on performance are undocumented.
Java reference properties
The same conclusions also hold true for Java objects, where it turns out that using handle() and the simple dot notation is 2-6 times as fast as using the Java set<PropName> and get<PropName> functions, due to Matlab-Java interface aspects:
jb = javax.swing.JButton; % Using the standard set() function tic, for idx=1:10000, set(jb,'Text','testing'); end, toc % Elapsed time is 0.278516 seconds. % Using the HG handle() wrapper is about 35% faster (or 1.6x speedup): jhb = handle(jb); tic, for idx=1:10000, set(jhb,'Text','testing'); end, toc % Elapsed time is 0.175018 seconds. % Using the HG handle() wrapper with dot notation is even faster (65% faster, or 2.8x speedup): tic, for idx=1:10000, jhb.text='testing'; end, toc % Elapsed time is 0.100239 seconds. % Using the Java setText() function, is actually slower (faster with the handle() wrapper, but still slower than dot-notation): tic, for idx=1:10000, jb.setText('testing'); end, toc % Elapsed time is 0.587543 seconds. tic, for idx=1:10000, jhb.setText('testing'); end, toc % Elapsed time is 0.201635 seconds.
The same holds true also for retrieving property values via the get function.
User handle class properties
Exactly the same conclusions also apply to non-graphical user classes that derive from the base handle class regarding property access. In this case, we derive the hgsetget built-in class, which provides a handle class with the standard get/set functions. Note that this is documented – it is only the performance implications that are undocumented in this case.
We first create a simple class for testing:
% Define a simple handle class classdef TestClass < hgsetget properties name end end
Now let’s test both sides of the property access (get/set) – first let’s set the property value:
obj = TestClass; % Using the standard set() function tic, for idx=1:10000, set(obj,'name','testing'); end, toc % Elapsed time is 0.138276 seconds. % Using class.propName notation - 72x faster! tic, for idx=1:10000, obj.name='testing'; end, toc % Elapsed time is 0.001906 seconds.
And similarly for retrieving a property value:
% Using the standard set() function tic, for idx=1:10000, a=get(obj,'name'); end, toc % Elapsed time is 0.105168 seconds. % Using class.propName notation - 6.5x faster tic, for idx=1:10000, a=obj.name; end, toc % Elapsed time is 0.016179 seconds.
Conclusions
The general conclusion is that we should always strive to use the dot notation (handle.propertyName
), rather than use the familiar get/set functions, in performance hotspots. Naturally, doing this in non-hotspot locations is futile, since accessing individual properties is relatively fast.
In the upcoming HG2, when all of Matlab's GUI and graphic objects will use Matlab classes, this conclusion will be more important than ever. Initial tests on the HG2 alpha (that anyone can access) show that they hold true for HG2 just as they do in the current HG1.
The handle() function wrapper produces a UDD (schema) object, so while I have not specifically tested non-HG schema objects, I would be very surprised if the conclusions do not hold true for all UDD objects in general.
I have also not [yet] tested other types of handles (ActiveX/COM, Dot-Net etc.) but again, I would be very surprised if the conclusions would be any different.
If this performance tip has piqued your interest, then you might be interested in the several hundred other tips in my upcoming book "MATLAB Performance Tuning" (CRC Press, 2014). I'll post a note on this blog letting everyone know when it's officially available. In the meantime, enjoy my other performance-related articles - there are already several dozen of them by now, and the list will continue to grow...
Editorial note: In the past month I've gone to quite a lot of effort to improve the performance of this website. Most users should now see pages loading about twice as fast as one month ago. The effect should be especially noticeable on mobile devices connected over mobile, which is much slower than wifi/cable. I still have a few additional tweak ideas, so I expect performance to slightly improve even further in the upcoming weeks. Enjoy reading!
Related posts:
- Displaying hidden handle properties I present two ways of checking undocumented hidden properties in Matlab Handle Graphics (HG) handles...
- Plot LimInclude properties The plot objects' XLimInclude, YLimInclude, ZLimInclude, ALimInclude and CLimInclude properties are an important feature, that has both functional and performance implications....
- Performance: scatter vs. line In many circumstances, the line function can generate visually-identical plots as the scatter function, much faster...
- Handle Graphics Behavior HG behaviors are an important aspect of Matlab graphics that enable custom control of handle functionality. ...