In both cases, the solution to the performance question can be found by simply using Matlab’s built-in profiler in order to extract just the core processing functionality. It is often found that in a particular situation there is no need for all the input arguments data validity checks, and under some known limitations we can indeed use the core functionality directly.

In the case of ismember, it turned out that if we are assured in advance that the input data are sorted non-sparse non-NaN values, then we can use the undocumented built-in helper functions ismembc or ismembc2 for much-improved performance over the standard ismember. Both ismembc and ismembc2 happen to be mex files, although this is not always the case for helper functions.

Our datenum case is very similar. It turns out that datenum uses the undocumented built-in helper function dtstr2dtnummx for the actual processing – converting a date from text to floating-point number. As I noted in my response to the StackOverflow question, we can directly use this helper function for improved performance: On my particular computer, dtstr2dtnummx is over 3 times faster than the standard datenum function:

While the difference in timing may appear negligible, if you are using this function to parse a text file with thousands of lines, each with its own timestamp, then these seemingly negligible time differences quickly add up. Of course, this only makes sense to do if you find out (using the profiler again) that this date parsing is a performance hotspot in your particular application. It was indeed such a performance hotspot in one of my applications, as it apparently was also for the original poster on StackOverflow.

Like ismembc, dtstr2dtnummx is an internal mex function. On my Windows system it is located in C:\Program Files\Matlab\R2011a\toolbox\matlab\timefun\private\dtstr2dtnummx.mexw32. It will have a different extension non-Windows systems, but you will easily find it in its containing folder.

To gain access to dtstr2dtnummx, simply add its folder to the Matlab path using the addpath function, or copy the dtstr2dtnummx.mexw32 file to another folder that is already on your Matlab path.

Note that the string format is different between dtstr2dtnummx and datenum: In the test case above, dtstr2dtnummx used 'yyyy-MM-dd HH:mm:ss', while datenum required 'yyyy-mm-dd HH:MM:SS'. I have no idea why MathWorks did not keep consistent formatting strings. But because of this, we need to be extra careful (example1, example2). If you are interested in finding out how the datenum format strings translates into a dtstr2dtnummx, take a look at the helper function cnv2icudf, which is a very readable m-file located in the same folder as dtstr2dtnummx.

To those interested, the folder that contains dtstr2dtnummx also contains some other interesting date conversion functions, so explore and enjoy!

Perhaps the main lesson that can be learned from this article, and its ismembc predecessor of two years ago, is that it is very useful to profile the code for performance hotspots. When such a hotspot is found, don’t stop your profiling at the built-in Matlab functions – keep digging in the profiler results and perhaps you’ll find that you can improve performance by taking an internal shortcut.

Have you discovered any other performance shortcuts in a built-in Matlab function? If so, please post a comment to tell us all about it.

Related posts:

datestr performanceCaching is a simple and very effective means to improve code performance, as demonstrated for the datestr function....

The speed is based on two methods: 1. the format has to be specified by a very limited set of 6 most common formats. 2. The value is not checked for validity: While DATENUM and DTSTR2DTNUMMX recognize ’2011-04-180′ more or less correctly as 179th day after 2011-04-01, DateStr2Num fails and does even not catch ’2011-04-AB’ as an error. To calculate the fractional part for ’25:61:62′, the overflow can be ignored fortunately.

Therefore, if you know that the date string is valid, a very simple C-code can be 100 times faster than DATENUM and 25 times faster than DSTR2DNUMMX.

The C-Mex DATENUMMX.c was part of Matlab 6.5. What a pitty that modern Matlab versions include less of such cookies.

The built-in DATENUMMX converts [1 x 6] date vectors 4 times faster than DATENUM. It is at least included in Matlab 5.3 to 2009a – I cannot check this in newer versions. As said already, the source code datenummx.c was shipped with Matlab 6.5.

Hello, Mathworks seem to have done some black magic – when I used older Matlab (2011), datenum conversion of a time vector (2.1*10^6 entries) with a given format took 600+ seconds. With DTSTR2DTNUMMX, it took 220 s. In Matlab 2013, it takes 28s only and seems to give a correct answer too! Best, Jakub

Recent Comments

Yair Altman (11 minutes 13 seconds ago): @Christina – sounds like something’s funky with your Java. Java warnings cannot be suppressed. You have a very old Matlab release so try upgrading to a newer release.

Christina (3 days 3 hours ago): In Matlab2007 I’m trying to use the JSlider but I keep getting a “Warning: Transform Fcn…” error every time the GUI repaints. I cannot find a way to get...

Ed Yu (3 days 4 hours ago): Yair, I would say with regard to loading classes through the java (root) classloader directly should not be that risky… As long as MATLAB is using Java, the root classloader...

sebastian (3 days 6 hours ago): Specifying relative paths in classpath.txt may not be supported, but for me it works just fine in R2011b. Simply add paths relative to the location of classpath.txt (i.e. relative...

Armindo (3 days 6 hours ago): Hi, I try to use the: function moveptr(hAx, x, y) However I get the following error Undefined function ‘getpos’ for input arguments of type ‘matlab.graphics.axis...

Martin (4 days 10 hours ago): @Mariam – you can also use the -struct flag of the save function, if you want to modify the struct s directly without going through another temporary variable: save('testFig.fig',...

Yair Altman (4 days 12 hours ago): @Mariam – the save command save the data including the variable name as top-level struct field. You should keep the same top-level field-name as used by the FIG format...

Mariam (4 days 17 hours ago): I tried it without making any changes to ‘s’. Just loading it s = load('C:\Users\Mariam\Desktop\ fitted response\atlas masks\IPS.fig','-mat'); and re-saving it...

mugurg (5 days 11 hours ago): If you want to use LaTeX interpreter of MATLAB, create .eps figures, and get the desired font (like Helvetica) instead of Computer Modern fonts, I think I’ve finally found a...

Yair Altman (5 days 12 hours ago): @Mariam – you can simply use the save command to save your modified d struct back into the *.fig file, and then open this FIG file normally: save('testFig.fig','d','-ma...

Mariam (5 days 14 hours ago): Hi, I have used above following command to load the attributes of figures d = load('testFig.fig','-mat') and then changed those attributes. I want to know how could I apply new...

Yaroslav (5 days 15 hours ago): So far, a smart solution is elusive; you can inspect Yair’s previous comment for a detailed analysis. In the meanwhile, you can try the old-school simple approach: N = 15;...

nasan (6 days 0 hours ago): Hi Yair, I’ve seen the demo but when I adapt it into my gui code gcbf is not recognize. How can I resolve it ? Can you give me a simply implementation in gui