5

I have an object from some class I wrote in Matlab. When I use "whos" command to determine its size, it is roughly 720,000 Bytes. When I save it in a .mat file it take roughly 75MB. What is going on?

Is there an efficient way of saving and loading an object in Matlab?

EDIT: Here is a list of the properties and their size

            CT_COL: 2
            p: 5
            d: 10
            n: 37
            N: 20
          idx: [20x1 double]
           Am: [4-D double]
            X: [4-D double]
            y: [37x1 double]
        KGram: [20x20 double]
       reWave: []
          rpw: 2
         grps: [1x37 double]
        exIDX: [1 4 5 6 13]
          nCV: 100
        prIDX: [100x6 double]
        trIDX: [100x26 double]
            U: [5x100 double]
            V: [10x100 double]
            B: [20x100 double]
         Yhat: [37x100 double]
          Lam: [100x1 double]
    peakRatio: [37x1 double]

Both Am and X are 20x10x5x37 arrays (of double)

By the way, the property "reWave" used to hold the handle of a method of another object. I thought that might not be a good idea (and might be causing this), so I have removed any mention of it from the class definition. But it seems to somehow appear in the set of properties. (Even after I have issued "clear classes".)

EDIT2: I am using the command save('uvXbMod1.mat','ob') to save just the object. Here comes the puzzling: When I use the command whos -file uvXbMod1.mat to see what is saved inside the file, it shows

Name      Size             Bytes   Class        Attributes

ob        1x1              680512  uvXbModel   

(This is for another instance, not the one mentioned above.) What else is put in the .mat file that makes it that big?

EDIT3: OK... The problem seemed to be two inline function handles I stored in two protected properties. Just these two, @(X) median(abs(X),2) and @median . The handles themselves were just a few bytes in size, and I assumed that since they are inline functions, they should just be stored along with their one-line definitions as text (?). But apparently that does not happen, it causes a huge amount of other things to be stored along (which doesn't seem that strange after the fact ...)

passerby51
  • 835
  • 2
  • 9
  • 23
  • 1
    Could you be a little more descriptive about the object? What is its type and what are its dimensions? – Ryan J. Smith Apr 25 '13 at 03:11
  • I have edited the post with a list of properties. – passerby51 Apr 25 '13 at 03:22
  • 2
    That object definitely seems consistent with your report of 720 kB or so. Is it possible you're saving the entire workspace and not just this object? – Ryan J. Smith Apr 25 '13 at 03:59
  • 1
    What is the command you are using for the save? It should be something like `save('myfile.mat', 'myobject')`. If you leave off the second parameter, then, as @RyanJ.Smith suggested, you would be saving your entire workspace - which could easily be 75M. A .mat file is typically much smaller than the size reported by `whos` since it's compressed. – Floris Apr 25 '13 at 05:27
  • 1
    How big are those 4D arrays? :) – Rody Oldenhuis Apr 25 '13 at 06:27
  • @Floris, I am using the command you mentioned (not saving the entire workspace, just that one variable) – passerby51 Apr 25 '13 at 10:29
  • @Ryan, I am not saving the entire workspace,and that is the thing that is puzzling me. – passerby51 Apr 25 '13 at 10:31
  • @Rody, those are 20 x 10 x 5 x 37. – passerby51 Apr 25 '13 at 10:31
  • I should also mention that there are some protected properties that are not showing, but those are empty in the instance that I am saving. – passerby51 Apr 25 '13 at 10:32
  • 1
    I am afraid that without being able to reproduce the issue we won't be of much help. I would recommend either to share the code or contact TMW support to retain privacy. – Oleg Apr 25 '13 at 11:00
  • 1
    Does the class have a `saveobj` method? Private properties? Superclasses? – Andrew Janke Apr 25 '13 at 11:18
  • 1
    OK so what if you ZIP the file? To what size does it compress? – Rody Oldenhuis Apr 25 '13 at 13:20
  • @RodyOldenhuis - that ought not to help. From -v7 (R7.0) onwards `.mat` is a compressed format. But yes, so "cruft" must be carried along. Just to be completely sure - can you (a) save to a new file (in case you have some `-append` option), and (b) tell us _exactly_ how you determined the file size? Clutching as straws now... – Floris Apr 25 '13 at 14:05
  • @Andrew, not it does not have saveobj, but thanks for that pointing out. – passerby51 Apr 25 '13 at 14:44
  • Thanks everyone for their contribution. I have figured out what was going on and updated my post. – passerby51 Apr 25 '13 at 14:46
  • 1
    Thanks for the update. I suggest you post this as an "answer" to your question; you will be able to "accept" it after a certain period and it will help others with the same problem find your solution! – Floris Apr 25 '13 at 15:16
  • 1
    That's not actually an "inline" function, that's an "anonymous" function. Inline functions are created with the `inline()` function, and they are stored as strings. Anonymous functions like this one here are stored as p-code like normal Matlab functions. – Andrew Janke Apr 25 '13 at 16:47
  • 1
    And they grab values. I think what happens is they store a snapshot of their entire enclosing workspace (all variable values) with them. The way Matlab defines it, inline functions keep a copy of each variable they reference in the enclosing workspace. But, since Matlab is so dynamic, with stuff like `eval`, the interpreter can't tell what variables an arbitrary expression will reference. So I think it just captures all of them as a conservative shortcut. (Though one would think they could optimize simple cases like yours here, which doesn't reference *any* variables or use `eval`.) – Andrew Janke Apr 25 '13 at 16:49
  • (And I don't mean to be picky here, just want to let you know what's going on. Good find!) – Andrew Janke Apr 25 '13 at 16:51

1 Answers1

5

Here is the issue that I have found with my code: The problem was two inline anonymous function handles I stored in two protected properties. Just these two, @(X) median(abs(X),2) and @median.

The handles themselves were just a few bytes in size, and I assumed that since they are inline anonymous functions, they should just be stored along with their one-line definitions as text. But apparently that does not happen, and it causes a huge amount of other things to be stored along.

passerby51
  • 835
  • 2
  • 9
  • 23
  • 2
    Again, not to be nitpicky, but these are "anonymous", not "inline" functions, and the distinction matters with respect to this topic: anonymous functions will capture copies of the workspace as happened to you, and inline functions will not. But +1 regardless. – Andrew Janke Apr 26 '13 at 01:47
  • Thanks, fixed. I am wondering how they compare in terms of speed. I remember seeing a post comparing the speed for various function calls in Matlab ... . – passerby51 Apr 26 '13 at 13:33
  • 1
    You mean this post? ;) http://stackoverflow.com/questions/1693429/is-matlab-oop-slow-or-am-i-doing-something-wrong/1745686#1745686. I don't know how inline functions compare for performance. IIRC they used to be slow, but they might be compiled down in to p-code like anonymous functions now. I don't know that they're actually stored as text internally and evaluated each time; just that you provide them as text and they don't capture values. – Andrew Janke Apr 26 '13 at 20:37
  • Thanks for the helpful link ... I guess that was it. – passerby51 Apr 27 '13 at 20:35