help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: avoiding copying arguments by value when calling a function


From: Sergei Steshenko
Subject: Re: avoiding copying arguments by value when calling a function
Date: Wed, 22 Aug 2012 15:40:42 -0700 (PDT)


--- On Mon, 8/20/12, Carnë Draug <address@hidden> wrote:

> From: Carnë Draug <address@hidden>
> Subject: Re: avoiding copying arguments by value when calling a function
> To: "Sergei Steshenko" <address@hidden>
> Cc: address@hidden
> Date: Monday, August 20, 2012, 7:15 AM
> On 20 August 2012 14:55, Sergei
> Steshenko <address@hidden>
> wrote:
> > Hello,
> >
> > if I understand correctly, if I write a function like
> this:
> >
> > function result = foo(bar)
> >   # function body goes here
> > endfunction
> >
> > and if I call the function this way
> >
> > result = foo(bar);
> >
> > , the 'bar' argument is copied by value each time 'foo'
> is called.
> >
> >
> > I was thinking of something like this:
> >
> >
> > bar_func = @() bar; # Octave accepts this
> >
> > function result = foo(bar_func)
> >   # function body goes here
> >   # whenever I need 'bar' I use
> bar_func() instead
> > endfunction
> >
> > - I tried this and it works, i.e. produces the expected
> result.
> >
> > If again I understand correctly, passing 'bar_func' is
> passing a function handle, which for large enough 'bar' data
> can hopefully yield better performance.
> >
> > Are my understandings correct ? I.e. can anonymous
> functions be used as data wrappers in order to avoid
> physical copying of data ?
> 
> I started some time ago a page on the wiki about
> performance
> http://wiki.octave.org/Performance and no, Octave does
> not use Copy by
> value. It's more like lazy copy. Seems the manual
> http://www.gnu.org/software/octave/doc/interpreter/Call-by-Value.html
> is incorrect.
> 
> I'm aware the wiki page it's quite incomplete and what was
> there I had
> discovered myself by creating a giant matrix, copying it
> around and
> measuring the time it took. Some time ago someone also asked
> about
> using global variables hence why there's a section named
> Global
> variables but I never tried that. If you investigate its
> use, please
> add it to the wiki.
> 
> Carnë

I am on slow Internet at the moment, so I won't ass anything to the Wiki.

Anyway, please find below a simple test script (I called it 
"global_vs_local.m"), and here are its results:

"
octave:16> source("/home/sergei/junk/global_vs_local.m");
f_of_global_x user time = 4.55231 total time = 13.133
f_of_local_x user time = 4.45032 total time = 12.915
f_of_global_x user time = 4.25235 total time = 12.884
f_of_local_x user time = 4.34534 total time = 12.947
f_of_global_x user time = 4.38833 total time = 12.859
f_of_local_x user time = 4.45032 total time = 13.04
f_of_global_x user time = 4.49032 total time = 13.223
f_of_local_x user time = 4.48732 total time = 13.166
octave:17> 
".

What I don like about the results is that total time is about 3x greater than 
user time - I suspect too many of 'malloc' involved.

OTOH it looks like global vs local variable is a non-issue.

Thanks,
  Sergei.

The script:

function r = f_of_global_x
  global ___x;
  r = ___x + 1;
endfunction


function r = f_of_local_x(x)
  r = x + 1;
endfunction

N = 1e6;
iterations = 1000;

global ___x;

___x = zeros(1, N);

x = ___x;


for outer_iter = 1:4
  [total_start_time, user_start_time, system_time] = cputime();
  for iter = 1:iterations
    r = f_of_global_x();
  endfor
  [total_end_time, user_end_time, system_time] = cputime();
  fprintf(stderr, "f_of_global_x user time = %g total time = %g\n", 
user_end_time - user_start_time, total_end_time - total_start_time);


  [total_start_time, user_start_time, system_time] = cputime();
  for iter = 1:iterations
    r = f_of_local_x(x);
  endfor
  [total_end_time, user_end_time, system_time] = cputime();
  fprintf(stderr, "f_of_local_x user time = %g total time = %g\n", 
user_end_time - user_start_time, total_end_time - total_start_time);
endfor



reply via email to

[Prev in Thread] Current Thread [Next in Thread]