5

As I understand, MATLAB cannot use pass by reference when sending arguments to other functions. I am doing audio processing, and I frequently have to pass waveforms as arguments into functions, and because MATLAB uses pass by value for these arguments, it really eats up a lot of RAM when I do this.

I was considering using global variables as a method to pass my waveforms into functions, but everywhere I read there seems to be a general opinion that this is a bad idea, for organization of code, and potentially performance issues... but I haven't really read any detailed answers on how this might impact performance...

My question: What are the negative impacts of using global variables (with sizes > 100MB) to pass arguments to other functions in MATLAB, both in terms of 1) performance and 2) general code organization and good practice.

EDIT: From @Justin's answer below, it turns out MATLAB does on occasion use pass by reference when you do not modify the argument within the function! From this, I have a second related question about global variable performance:

Will using global variables be any slower than using pass by reference arguments to functions?

RTbecard
  • 868
  • 1
  • 8
  • 23
  • 1
    One of the pitfalls in terms of *good practise* is that you can suddenly overwrite a variable which is used inside a function in other functions. Therefore it can be difficult to keep track of changes and going back and forth between functions might cause unexpected behaviour because of that. This happens especially often if you call your global variables things like `h`, `a` etc (this of course makes for bad reading also when the variable is not `global`) – Adriaan Dec 24 '15 at 10:17
  • 1
    [This post](http://www.matlabtips.com/variable-scope-memory-spaces-in-matlab/) on matlabtips.com explains a bit more about the different types of variables and why using `global` is generally frowned upon. – Adriaan Dec 24 '15 at 10:23
  • 1
    Related: [“GLOBAL could be very inefficient”](http://stackoverflow.com/q/7888899/2278029) and [Don't use global, don't use eval](http://www.mathworks.com/matlabcentral/answers/51946-systematic-do-not-use-global-don-t-use-eval). And Matlab can [use pass by reference](http://www.mathworks.com/matlabcentral/answers/152-can-matlab-pass-by-reference) in the case of OOP. Yes, global variables will be slower (test it yourself) and they will also make your code less maintainable and understandable. – horchler Dec 24 '15 at 18:12

4 Answers4

7

MATLAB does use pass by reference, but also uses copy-on-write. That is to say, your variable will be passed by reference into the function (and so won't double up on RAM), but if you change the variable within the the function, then MATLAB will create a copy and change the copy (leaving the original unaffected).

This fact doesn't seem to be too well known, but there's a good post on Loren's blog discussing it.

Bottom line: it sounds like you don't need to use global variables at all (which are a bad idea as @Adriaan says).

Justin
  • 1,980
  • 1
  • 16
  • 25
  • good, however does using global variables actually affect performance (in a negative way)? i would say not – Nikos M. Dec 24 '15 at 10:40
  • @NikosM. yes it does, see the post by Loren and the one I linked above (also click through to the wiki page on [global variables](https://en.wikipedia.org/wiki/Global_variable)) – Adriaan Dec 24 '15 at 10:44
  • 1
    read the article (plus some of the top comments, not all), but does not mention anything about using global variables and especialy their performance vs variables passed as arguments, the wiki article does not mention matlab-specific information nor performance information – Nikos M. Dec 24 '15 at 10:50
  • Great answer! But there are some situations where I do need to modify the contents of the argument (like applying a calibration to my waveform), but thanks for correcting my misconception about `pass by reference` in MATLAB! @Adriaan I'm with @Nikos M. in that the posts did touch upon exceptions to copy on write, but I did not see any specific mentioning or examples of global variable performance. From @Justin's awesome answer here, I've added an additional part to my question which I think will further clarify my understanding of global variable performance. – RTbecard Dec 24 '15 at 11:54
  • This answer combined with @horchler's comment on my question has given me a pretty good overview about the performance of global variables and under what circumstances I'd need to use them. – RTbecard Dec 24 '15 at 22:55
3

While relying on copy on write as Justin suggested is typically the best choice, you can easily implement pass by reference. With Matlab oop being nearly as fast as traditional functions in Matlab 2015b or newer, using handle is a reasonable option.

Nikos M.
  • 8,033
  • 4
  • 36
  • 43
Daniel
  • 36,610
  • 3
  • 36
  • 69
  • I'm looking into this now, but this sounds like its the best option, as I do occasionally need to modify my argument values within the functions, so @Justin answer, while awesome, is not always applicable. – RTbecard Dec 24 '15 at 11:59
  • If I understand this right... in order to 'force a `pass by reference`' in situations when I am modifying the passed argument values within the function, for lets say a matrix object, would I have to make a user-defined `matrix` class which is a subclass of `Handle`? In the documentation, it describes that some objects are handles, how handles behave, and how to check if an object is a handle, but no information on how I can convert a `non-handle object` into a `handle object` (if that is in fact possible). – RTbecard Dec 24 '15 at 12:26
  • I don't have access to Matlab within the next days, if anyone can provide additional information feel free to update my answer. – Daniel Dec 24 '15 at 12:45
3

I encountered an interesting use case of a global variable yesterday. I tried to parallellise a piece of code (1200 lines, multiple functions inside the main function, not written by me), using parfor.

Some weird errors came out and it turned out that this piece of code wrote to a log file, but used multiple functions to write to the log file. Rather than opening and closing the relevant log file every time a function wanted to write to it, which is very slow, the file ID was made global, so that all write-functions could access it.

For the serial case this made perfect sense, but when trying to parallellise this, using global apparently breaks the scope of a worker instance as well. So suddenly we had 4 workers all trying to write into the same log file, which resulted in some weird errors.

So all in all, I maintain my position that using global variables is generally a bad idea, although I can see its use in specific cases, provided you know what you're doing.

Adriaan
  • 17,741
  • 7
  • 42
  • 75
2

Using global variables in Matlab may increase performance alot. This is because you can avoid copying of data in some cases.

Before attempting to gain such performance tweaks, think carefully of the cost to your project, in terms of the many drawbacks that global variables come with. There are also pitfalls to using globals with bad consequences to performance, and those may be difficult to avoid(although possible). Any code that is littered with globals tend to be difficult to comprehend.

If you want to see globals in use for performance, you can look at this real-time toolbox for optical flow that I made. This is the only project in native Matlab that is capable of real-time optical flow that I know of. Using globals was one of the reasons this was doable. It is also a reason to why the code is quite difficult to grasp: Globals are evil.

That globals can be used this way is not a way to argue for their use, rather it should be a hint that something should be updated with Matlabs unflexible notions of workspace and inefficient alternatives to globals such as guidata/getappdata/setappdata.

Community
  • 1
  • 1
Stefan Karlsson
  • 1,092
  • 9
  • 21
  • 1
    "...may increase performance" compared to another poor design. The question you linked in turn links to [this post](https://www.mathworks.com/matlabcentral/answers/99537-which-type-of-function-call-provides-better-performance-in-matlab), which states globals interfere with the JIT. That makes a lot of sense. Passing a variable to a function as an argument should always be preferred over using a global variable. – Cris Luengo Apr 06 '18 at 20:01
  • @Cris Luengo. There is a reason why that poor design is available as fully supported Matlab functions (guidata, getappdata, setappdata), because there is a need for it. If you have ever designed a GUI with Matlab that handles larger data amounts with speed, you would know why. But you know what, Matlab shouldnt be used to get this sort of speed anyway. When you get to the point that using globals is a viable speed up, change language as your prototyping is done. – Stefan Karlsson Apr 08 '18 at 08:50