Fastest way to sum the elements of a matrix

414 Views Asked by At

I have some problems with the efficiency of my code. Basically my code works like this:

a = zeros(1,50000);
for n = 1:50000
    a(n) = 10.*n - 5;
end
sum(a);

What is the fastest way to solve the sum of all the elements of this matrix?

1

There are 1 best solutions below

15
GameOfThrows On BEST ANSWER

first you want to remove your for loop by making it a vector multiplication:

tic
a = zeros(1,50000);
b = [1:50000];
   a = 10.*b-5;
result = sum(a);
toc
Elapsed time is 0.008504 seconds.

An alternative way is to simplify your operation, you are multiplying 1 to 50000 by 10 and subtracting 5 then taking the sum (which is a single number), which is equivalent to:

tic
result = sum(1:50000)*10 - 5*50000;
toc
Elapsed time is 0.003851 seconds.

or if you are really into Math (this is a pure mathematical expression approach) :

tic
result = (1+50000)*(50000/2)*10 - 5*50000;
toc
Elapsed time is 0.003702 seconds.

and as you can see, a little math can do greater good than pure efficient programming, and actually, loop is not always slow, in your case, the loop is actually faster than the vectorized method:

tic
a = zeros(1,50000);
  for n = 1:50000
     a(n)=10.*n-5;
  end
sum(a);
toc
Elapsed time is 0.006431 seconds.

Timing

Let's do some timing and see the results. The function to run it yourself is provided at the bottom. The approximate execution time execTime is in seconds and the percentage of improvement impPercentage in %.

Results

  • R2016a on OSX 10.11.4

                   execTime     impPercentage
                  __________    _____________
    loop          0.00059336         0       
    vectorized    0.00014494    75.574       
    adiel         0.00010468    82.359       
    math          9.3659e-08    99.984       
    

Code

The following function can be used to generate the output. Note that it requires minimum R2013b to be able to use the built-in timeit-function and table.

function timings
%feature('accel','on')      %// commented out because it's undocumented
cycleCount = 100;
execTime = zeros(4,cycleCount);
names = {'loop';'vectorized';'adiel';'math'};
w = warning;
warning('off','MATLAB:timeit:HighOverhead');
for k = 1:cycleCount
    execTime(1,k) = timeit(@()loop,1);
    execTime(2,k) = timeit(@()vectorized,1);
    execTime(3,k) = timeit(@()adiel,1);
    execTime(4,k) = timeit(@()math,1);
end
warning(w);
execTime = min(execTime,[],2);
impPercentage = (1 - execTime/max(execTime)) * 100;
table(execTime,impPercentage,'RowNames',names)


function result = loop
a = zeros(1,50000);
for n = 1:50000
    a(n) = 10.*n - 5;
end
result = sum(a);

function result = vectorized
b = 1:50000;
a = 10.*b - 5;
result = sum(a);

function result = adiel
result = sum(1:50000)*10 - 5*50000;

function result = math
result = (1+50000)*(50000/2)*10 - 5*50000;