Is calling length() as needed slower than storing the value just once in a separate variable?

5 views (last 30 days)
Christopher Wong
Christopher Wong on 13 Apr 2020
Commented: dpb on 14 Apr 2020
The question really is: are the dimensions of an array stored somewhere on the stack, or does the length() function perform some calculation everytime it is called? I can obviously store the length of some array dimension in a separate variable, and thus, only call length() once, and then just reference the variable wherever I need this integer value. But, sometimes, the code just looks cleaner and clearer when I call length() everytime I need this value.
I am in a position where I am reinitializing a nested for loop for every outer for loop iteration, and I am using length() to define the nested loop's boundaries. But if length() is a function that takes some time everytime its called, it would obviously be more efficient to call length() just once and store its value.
  4 Comments

Sign in to comment.

Accepted Answer

dpb
dpb on 13 Apr 2020
Edited: dpb on 13 Apr 2020
Any computation has a finite speed...even memory access alone.
Builtin data types contain a knowledge of the dimensions allocated, yes (else't there would be no error that you just exceeded array bounds in indexing expressions).
I suspect whether the JIT compiler can cache the result of a length() call is minimal at best since one can always redimension silently in MATLAB it would be only verifiably static cases where could be possible and that's (I'm guessing) probably more expensive than the cost.
So, while this is conjecture (I looked a little on Yair's site to see if he had any background info on subject but couldn't find quickly), I think one can be assured that as David says, when you call length it is executed. functions are cached, I suspect the largest overhead with length is the determination of which method to call...try
which -all length
to see how many instantiations there are on your system--this is a fairly plain vanilla install with a limited number of toolboxen and there are 20-some associated with those few toolboxes besides the 10 or so built-in versions.
However, I would still suspect it is unlikely to be the bottleneck in any code of any real complexity unless you've truly got a million of 'em scattered around.
Like always, it's also premature to try to peephole optimize until you have profiled the code to find out where the peformance bottleneck(s) is/(are). You could eliminate 100% of a particular calculation but if that's only a small fraction of the total, you've still gained virtually nothing.
Write clearest code you can first, only if it is shown to be unsatisfactory in performance, then profile and work on those areas. Don't try to outguess...
  3 Comments
dpb
dpb on 14 Apr 2020
"I'm always subconsciously trying to balance friendly scripting and performance optimization whilst I write code"
Besides the TMW links Stephen provided, Yair has many hints and much to learn at <tips-for-accelerating-matlab-performance>

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 13 Apr 2020
function test_speed
foo = zeros(randi(255),randi(255),randi(255));
f1 = @() length(foo);
Lfoo = length(foo);
f2 = @() Lfoo;
N = 256;
t1 = zeros(N,1);
t2 = zeros(N,1);
t3 = zeros(N,1);
t4 = zeros(N,1);
ws = warning('off','MATLAB:timeit:HighOverhead');
cleanme = onCleanup(@() warning(ws));
fprintf('testing length first time\n');
for K = 1 : N; t1(K) = timeit(f1,0); end
fprintf('testing stored length first time\n');
for K = 1 : N; t2(K) = timeit(f2,0); end
fprintf('testing length second time\n');
for K = 1 : N; t3(K) = timeit(f1,0); end
fprintf('testing stored length second time\n');
for K = 1 : N; t4(K) = timeit(f2,0); end
plot([t1,t2,t3,t4])
legend({'length', 'stored', 'length again', 'stored again'})
fprintf('mean length = %g %g\n', mean(t1), mean(t3));
fprintf('mean stored = %g %g\n', mean(t2), mean(t4));
end
You will not get the same results for a script! JIT for functions is different than JIT for a script!
You will not necessarily see the same results for the second run as for the first run! Historically, the first run of any timing test has been notably slower than the second run of the timing test, and that has been on a per line basis, not just a first-time overhead for the very first run. Historically, t3 and t4 would have been notably faster than t1 and t2, even though they invoke exactly the same code.
With time differences as small as these, you have to be very careful about exactly what you are timing.

Products


Release

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!