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: Juan Pablo Carbajal
Subject: Re: avoiding copying arguments by value when calling a function
Date: Thu, 23 Aug 2012 14:36:21 +0200

On Thu, Aug 23, 2012 at 12:40 AM, Sergei Steshenko <address@hidden> wrote:
>
>
> --- 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
>
> _______________________________________________
> Help-octave mailing list
> address@hidden
> https://mailman.cae.wisc.edu/listinfo/help-octave

 As was mentioned. You observe a difference when you use the functions
in your script (erasing the expected outputs)

function f_of_global_x
  global ___x;
  ___x += 1;
endfunction

function f_of_local_x(x)
  x += 1;
endfunction

My results
f_of_global_x user time = 3.68023 total time = 3.70423
f_of_local_x user time = 2.97619 total time = 9.03256
f_of_global_x user time = 3.68423 total time = 3.68823
f_of_local_x user time = 3.1242 total time = 9.04056
f_of_global_x user time = 3.68823 total time = 3.69623
f_of_local_x user time = 3.04019 total time = 9.04856
f_of_global_x user time = 3.78424 total time = 3.79224
f_of_local_x user time = 3.1962 total time = 9.34858


-- 
M. Sc. Juan Pablo Carbajal
-----
PhD Student
University of Zürich
http://ailab.ifi.uzh.ch/carbajal/


reply via email to

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