views:

103

answers:

1

Recently I profiled some MATLAB code and I was shocked to see the following in a heavily used function:

5.76  198694   58 persistent CONSTANTS; 
3.44  198694   59 if isempty(CONSTANTS) % initialize CONSTANTS

In other words, MATLAB spent about 9 seconds, over 198694 function calls, declaring the persistent CONSTANTS and checking if it has been initialized. That represents 13% of the total time spent in that function.

Do persistent variables really carry that much of a performance penalty in MATLAB? Or are we doing something terribly wrong here?

UPDATE

@Andrew I tried your sample script and I am very, very perplexed by the output:

time   calls  line
                6 function has_persistent
6.48  200000    7 persistent CONSTANTS 
1.91  200000    8 if isempty(CONSTANTS) 
                9     CONSTANTS = 42;
               10 end

I tried the bench() command and it showed my machine in the middle range of the sample machines. Running Ubuntu 64 bits on a Intel(R) Core(TM) i7 CPU, 4GB RAM.

+4  A: 

That's the standard way of using persistent variables in Matlab. You're doing what you're supposed to. There will be noticable overhead for it, but your timings do seem kind of surprisingly high.

Here's a similar test I ran in 32-bit Matlab R2009b on a 3.0 GHz Intel Core 2 QX9650 machine under Windows XP x64. Similar results on other machines and versions. About 5x faster than your timings.

Test:

function call_has_persistent
for i = 1:200000
    has_persistent();
end

function has_persistent
persistent CONSTANTS
if isempty(CONSTANTS)
    CONSTANTS = 42;
end

Results:

  0.89  200000    7 persistent CONSTANTS 
  0.25  200000    8 if isempty(CONSTANTS) 

What Matlab version, OS, and CPU are you running on? What does CONSTANTS get initialized with? Does Matlab's bench() output seem reasonable for your machine?

Your timings do seem high. There may be a bug or config issue there to fix. But if you really want to get Matlab code fast, the standard advice is to "vectorize" it: restructure the code so that it makes fewer function calls on larger input arrays, and makes use of Matlab's built in vectorized functions instead of loops or control structures, to avoid having 200,000 calls to the function in the first place. If possible. Matlab has relatively high overhead per function or method call (see http://stackoverflow.com/questions/1693429/matlab-oop-is-it-slow-or-am-i-doing-something-wrong/1745686#1745686 for some numbers), so you can often get more mileage by refactoring to eliminate function calls instead of making the individual function calls faster.

It may be worth benchmarking some other basic Matlab operations on your machine, to see if it's just "persistent" that seems slow. Also try profiling just this little call_has_persistent test script in isolation to see if the context of your function makes a difference.

Andrew Janke