2

Can someone explain why there is a significant time difference?

function [] = maincalc ()

ak=am();

t1=tic;
[out] = myfun (ak.aa, ak.b, ak.c, ak.d, ak.e, ak.f, ak.g, ak.h);
to1end=toc(t1)

t2=tic;
[out2] = myfun2 (ak);
to2end=toc(t2)

the result:

to1end =
   0.047520231560659
to2end =  
  12.490895284055467

class am ( I know someone might say that there is no reason to use class for this, but the whole code is the simplification of a much more complex and long code, and class is necessary):

classdef am 
    properties
        aa = 1;
        b = 2;
        c = 3;
        d = 4;
        e = 2.3;
        f = 4.2;
        g = 5.09;
        h = 12.3;
    end
end

function myfun:

function [out] = myfun (aa, b, c, d, e, f, g, h)
n = 500000;
i = 0; j = 0; k = 0; l = 0;
for s = 1:n
    i = aa/b + j*k - i;
    j = c/d ^ 0.5 - j / i;
    k = e*f + aa/3 - k/8;
    l = g + exp (h) + l ^ -1;
end
out.i = i;
out.j = j;
out.k = k;
out.l = l;

function myfun2:

function [out] = myfun2 ( ak )
n = 500000;
i = 0; j = 0; k = 0; l = 0;
for s = 1:n
    i = ak.aa/ak.b + j*k - i;
    j = ak.c/ak.d ^ 0.5 - j / i;
    k = ak.e*ak.f + ak.aa/3 - k/8;
    l = ak.g + exp (ak.h) + l ^ -1;
end
out.i = i;
out.j = j;
out.k = k;
out.l = l;

I have read somewhere someone explaining about MATLAB's copy-on-write, but that doesn't really apply here since there is no changes made to any member of the class.

================================================================================== details below this line was recently added on 8/2/2013

Marcin responded that it has not much to do with the way MATLAB passes parameters to functions (great discovery by the way!), but I think it still has something to do with it. I've made another code, and this time all three approaches need to access the class multiple times:

function [] = maincalc3 ()

inputvar=inputclass();

to1end = 0;
to2end = 0;
to3end = 0;
j = 100;

for i = 1:j;
    t1=tic;
    [out] = func1 (inputvar);
    to1end=toc(t1) + to1end;

    t2=tic;
    [out2] = func2 (inputvar.s);
    to2end=toc(t2) + to2end;

    t3=tic;
    [out3] = func3 (inputvar);
    to3end=toc(t3) + to3end;
end

..............................

classdef inputclass
    properties
        s  = 1;
    end
end

...............................

function f = func1 (inputvar)
    f = inputvar.s;
end

...............................

function f = func2 (s)
    f = s;
end

...............................

function [f] = func3 (inputvar)
    s=inputvar.s;
    f = s;
end

and the result:

to1end =
   0.002419525505078
to2end =
   0.001517134538850
to3end =
   0.002353777529397

func1() and func3() takes about the same time, but func2 takes about 60% less time. Doesn't that mean the way MATLAB pass parameters to functions - by values or by objects - does affect the performance?

saiful
  • 71
  • 1
  • 5
  • 1
    OOP in Matlab is slow. Property access may cost much more time than local variables. Even worse when adding method get/set. You can check this page: http://stackoverflow.com/questions/1693429/is-matlab-oop-slow-or-am-i-doing-something-wrong – Yuan Aug 01 '13 at 02:02
  • Yea I agree, it's the best if OOP can be avoided. But my task now is to figure out why it is taking more time. – saiful Aug 02 '13 at 17:13

1 Answers1

4

I think it has not much to do with passing object by value or reference into a function. Its simply because in your loop, in myfun2() matlab needs to access object and its fields multiple times. That's it.

For example, if u make a third function called myfun3() as follows:

function [out] = myfun3 (ak)
n = 500000;
i = 0; j = 0; k = 0; l = 0;

% FOLLOWING LINE IS NEW <-----
% REMOVE object refencese from within the loop and create local variables
% to use in the loop, instead of referencing object properties all the time.
aa = ak.aa; b = ak.b; c=ak.c; d=ak.d; e=ak.e; f=ak.f; g=ak.g; h=ak.h;

for s = 1:n
    i = aa/b + j*k - i;
    j = c/d ^ 0.5 - j / i;
    k = e*f + aa/3 - k/8;
    l = g + exp (h) + l ^ -1;
end
out.i = i;
out.j = j;
out.k = k;
out.l = l;

The execution of this function is even slightly faster than myfun1(). On my PC the resutls are:

to1end =

    0.0533


to2end =

   23.9410


to3end =

    0.0526 % RESULT for myfun3() function
Marcin
  • 215,873
  • 14
  • 235
  • 294
  • Great discovery, Marcin! I added new details to the question, I hope you can take a look on that too. – saiful Aug 02 '13 at 17:05