Loren on the Art of MATLAB

April 19th, 2006

High Performance File I/O

Today I'd like to tell you how you might improve the performance of reading and writing files using MATLAB's low-level file i/o functions. The key here is to disable the automated buffer flushing.

Experience at MathWorks

The default behavior for fprintf and fwrite is to flush the file buffer after each call to either of these functions. This can have a noticeable performance impact if you are calling either of these functions many times to write small chunks of data each time.

MATLAB has a way to disable the auto-flushing, which is to fopen the file using mode 'W' instead of 'w' (or 'A' instead of 'a' for append). Since fclose also flushes the file, if you have a function that fopens a file, writes small chunks of data to it many times, and then fcloses it, you might want to consider changing your fopen mode.

We made made this change inside wk1write.m recently. When writing out a 200x200 array of doubles using wk1write, the elapsed time shrank from 6.55 seconds down to 4.34 seconds, a savings of 50%.

This technique won't work well if you are in the situation where you need to both read and write to the same file often throughout processing. For that, you need to flush the buffer after each call.

What sorts of file reading/writing bottlenecks do you encounter? Will this tip help you? Let me know.

6 Responses to “High Performance File I/O”

  1. John O'Leary replied on :

    I haven’t used it in awhile, but last time I did movie2avi seemed to run much slower than it should. I looked through the code and it seemed that the avi file created by this function was being opened and closed for every frame. After reading this post, I went back and looked at addframe.m again and I see this line (308):

    fid = fopen(filename,’a',’l');

    Could it be that simply changing the ‘a’ to ‘A’ here would speed up the writing of a movie to an avi file?

  2. Pat Cantey replied on :

    When using this technique, is the only way to flush the buffer to call fclose?

    Or is there some other function call that will flush?

    Or does it automatically flush when the buffer reaches its limit? If so, what is the limit (in bytes)?

  3. gianni replied on :

    Loren,
    I am writting in connection to a recent answer given by you to on the newsgroup and concerning out of memory problems …

    Also with the most recent version of matlab (2006a) there are cases of routines that do not support single precision

    In my view this is a major problem for many users of matlab,
    and huge memory boards do not help as much as a matlab tuning to make single precison always possible

    I have a direct experience with stream3 that cannot be forced to use single precison and uses 3 huge gradient arrays in double

    thank you , Gianni
    %%%%%
    Chris
    >>
    > MATLAB supports arithmetic and lots of other math on singles for
    > MATLAB
    > 7. Perhaps upgrading would be beneficial for you.

  4. Loren replied on :

    I would recommend in the future sending information like this to our Technical Support group. They pass information like this along to the development team who then prioritize their work with user requests in mind. The link is:

    http://www.mathworks.com/support/contact_us/ts/ebd/enhance_bug_doc_1.html

  5. Loren replied on :

    Pat-

    The only way to guarantee the buffer is flushed is to use fclose if you open with A or A. Using a or w flushes the buffer after each write.

    –Loren

  6. Eric replied on :

    Wow! That was a good one.

    I use a lot of fprintf in link level simulations of communication systems. The data is printed to files frame-by-frame, and the files are used to test Verilog implementation of the actual modem hardware.

    I’ve just tried your tip, and savings in simulation time are tremendous.

    Thank you!

    Eric

Leave a Reply

Wrap code fragments inside <pre> tags, like this:

<pre class="code">
a = magic(3);
sum(a)
</pre>

If you have a "<" character in your code, either follow it with a space or replace it with "&lt;" (including the semicolon).


Loren Shure works on design of the MATLAB language at The MathWorks. She writes here about once a week on MATLAB programming and related topics.

  • Jun: I totally can not believe it, Loren. You are really helpful. Thank you so much, MATLAB master!
  • Loren: Wow folks- Always lots of interest when there’s a quickie to try out! I will only make 2 general...
  • Loren: Jun- ismember is your friend here: >> [aa,ind] = ismember(Array2,Arra y1) aa = 1 1 1 1 1 1 1 ind = 1 2 1 4 4 3...
  • Dan: I like the first way better than the second way. Combining the arrays into one and running any is nice, although...
  • James Myatt: How about I = (a == 0 | b == 0); a(I) = []; b(I) = [];
  • Tunc: Hello Loren, love your blog because of such inspiring and challenging comments to such ’small’...
  • Pekka Kumpulainen: Here is my tradeoff. I usually want to keep the original variables as they are most probably...
  • Iain: Followup: Of course, to allow NaNs (counting them as non-zero): mask = (a~=0) & (b~=0); The mask says “a...
  • Matt Fig: I would usually go with something like this: y = a&b; x = a(y); y = b(y); But I was surprised to find...
  • kk: c=all([a;b]) a(c) a(b)

These postings are the author's and don't necessarily represent the opinions of The MathWorks.