3

I have a snippet of code which takes a vector A and creates a new vector C by summing A with both a left and right shifted version of itself (this is based on a centered finite difference formula ). For example, if A = [1 2 3 4 5], then C = [0 6 9 12 0], where the edges are zero because these don't have entries on both sides.

I created two versions, one which loops over element by element in C, and a second which processes the whole array. I measure the "vectorised" version to be around 50 times slower than the loop version... I was expecting the vectorised version to offer a speed improvement, but seems like it is not the case - what am I missing?

A = [1 2 3 4 5];
N = length(A);

C1 = zeros([1, N]);
C2 = zeros([1, N]);

%%% Loop version, element by element %%%
tic
for ntimes = 1:1e6
    for m = 2:(N-1)
        C1(m) = A(m+1) + A(m-1) + A(m);
    end
end
t1 = toc;
disp(['Time taken for loop version = ',num2str(t1)])

%%% Vector version, process entire array at once %%%
tic
for ntimes = 1:1e6
    C2(2:(N-1)) = A(3:N) + A(1:(N-2)) + A(2:(N-1));
end
t2 = toc;
disp(['Time taken for vector version = ',num2str(t2)])
teeeeee
  • 641
  • 5
  • 15
  • 3
    For small sizes these things can happen, but they are not very representative. Try for example `A = 1:1e4;` and `for ntimes = 1:1e3` and you'll get similar results in both cases, with the vectorized approach being slightly faster (tested on R2017b). The most likely explanation is that for small sizes of `A` the running time of the vectorized approach is dominated by the creation of the index arrays `2:(N-1)` etc. Also, putting the code in a function can produce different time results – Luis Mendo Nov 24 '20 at 17:25
  • 2
    Anyway, it seems difficult to obtain a definitive answer. It may depend on things such as computer architecture and Matlab version. It is likely related to JIT, but JIT changes across versions, is not documented, and seems to be [deactivated](https://www.mathworks.com/matlabcentral/answers/18576-profiler-biases-execution-time-of-optimized-code) by `profile`, which is precisely what you would use to look into this... – Luis Mendo Nov 24 '20 at 18:35
  • 2
    There’s “common wisdom” that MATLAB arrays are slow. This was true 20 years ago, but hasn’t been since. In fact, they’re faster every release. Vectorizing sometime is beneficial, sometimes is not. There are a lot of questions on this site where it is shown that the loop version of the code is faster than any of the possible vectorized versions. – Cris Luengo Nov 24 '20 at 18:57
  • For example this is an interesting read if you care about efficiency in MATLAB code: https://stackoverflow.com/q/13382155/7328782 – Cris Luengo Nov 24 '20 at 18:59
  • N.B. Did you also compare with `conv(A, [1 1 1], 'valid')`? – chtz Nov 24 '20 at 21:48
  • @chtz Just tried it myself, it provides similar results to the vectorized code. – Daniel Aldrich Nov 24 '20 at 22:50
  • 3
    as soon as `A` becomes larger than 400 entries, the behavior flips, eg. `A = 1:5e2`. Vectorization creates a small overhead (it won't come for free). With complicated or large calculations, this overhead is negligible. Even in your example, the overhead is very small but sums up over `1e6` calls (the average overhead is somewhere at 2e-6s). However, usually you shouldn't worry about this because vectorization also keeps your code concise and readable, which is also a benefit – max Nov 25 '20 at 07:08

0 Answers0