Performance: Difference between revisions
Carandraug (talk | contribs) (Created page with "Things to consider when writing octave code to have good performance. They relate to how the interpreter works. == Writing functions == === Default arguments === It is possib...") |
Carandraug (talk | contribs) m (use octave syntax highlight) |
||
(3 intermediate revisions by 2 users not shown) | |||
Line 5: | Line 5: | ||
It is possible to set [http://www.gnu.org/software/octave/doc/interpreter/Default-Arguments.html default values] when declaring the function arguments. This defaults can be the result of a computation, maybe even using the other arguments: | It is possible to set [http://www.gnu.org/software/octave/doc/interpreter/Default-Arguments.html default values] when declaring the function arguments. This defaults can be the result of a computation, maybe even using the other arguments: | ||
{{Code|Defining argument defaults|< | {{Code|Defining argument defaults|<syntaxhighlight lang="octave" style="font-size:13px"> | ||
function foo (arg1, arg2 = heavyfoo (arg1)) | function foo (arg1, arg2 = heavyfoo (arg1)) | ||
## code | ## code | ||
endfunction | endfunction | ||
</ | </syntaxhighlight>}} | ||
One could think of setting defaults inside a condition checking the value of {{Codeline|nargin}} to avoid computing heavyfoo. However the interpreter will not generate the default value if the value is already given so it ends up being the same thing. That is, don't try to be smart, the interpreter already is, and write defaults on the list of arguments for code that is shorter and easier to read. | One could think of setting defaults inside a condition checking the value of {{Codeline|nargin}} to avoid computing heavyfoo. However the interpreter will not generate the default value if the value is already given so it ends up being the same thing. That is, don't try to be smart, the interpreter already is, and write defaults on the list of arguments for code that is shorter and easier to read. | ||
{{Code|Proof that interpreter does not compute defaults unless needed|< | {{Code|Proof that interpreter does not compute defaults unless needed|<syntaxhighlight lang="octave" style="font-size:13px"> | ||
function defaults_at_list (arg = rand (10000)) | function defaults_at_list (arg = rand (10000)) | ||
## just a simple operation | ## just a simple operation | ||
Line 30: | Line 30: | ||
t = cputime (); defaults_at_list (a); t_list = cputime () - t | t = cputime (); defaults_at_list (a); t_list = cputime () - t | ||
t = cputime (); defaults_at_cond (a); t_cond = cputime () - t | t = cputime (); defaults_at_cond (a); t_cond = cputime () - t | ||
</ | </syntaxhighlight>}} | ||
=== Function arguments (lazy copying) === | === Function arguments (lazy copying) === | ||
When passing variables to a function, Octave will only make a copy of it is going to be modified. That is, unless the argument needs to be changed, the variable will be like a reference and take no extra memory or time to write. | When passing variables to a function, Octave will only make a copy of it is going to be modified. That is, unless the argument needs to be changed, the variable will be like a reference and take no extra memory or time to write. | ||
{{Code|Looking at lazy copying|< | {{Code|Looking at lazy copying|<syntaxhighlight lang="octave" style="font-size:13px"> | ||
function read_arg (arg) | function read_arg (arg) | ||
x = arg(1); | x = arg(1); | ||
Line 52: | Line 52: | ||
t = cputime (); modi_arg (a); t_read = cputime () -t ## takes some time since a copy of a will be made to be modified | t = cputime (); modi_arg (a); t_read = cputime () -t ## takes some time since a copy of a will be made to be modified | ||
t = cputime (); chan_arg (a); t_read = cputime () -t ## takes NO time since even though arg is modifed, it's not based on the original value | t = cputime (); chan_arg (a); t_read = cputime () -t ## takes NO time since even though arg is modifed, it's not based on the original value | ||
</ | </syntaxhighlight>}} | ||
=== Global variables === | === Global variables === |
Latest revision as of 17:31, 18 June 2012
Things to consider when writing octave code to have good performance. They relate to how the interpreter works.
Writing functions[edit]
Default arguments[edit]
It is possible to set default values when declaring the function arguments. This defaults can be the result of a computation, maybe even using the other arguments:
Code: Defining argument defaults |
function foo (arg1, arg2 = heavyfoo (arg1))
## code
endfunction
|
One could think of setting defaults inside a condition checking the value of nargin
to avoid computing heavyfoo. However the interpreter will not generate the default value if the value is already given so it ends up being the same thing. That is, don't try to be smart, the interpreter already is, and write defaults on the list of arguments for code that is shorter and easier to read.
Code: Proof that interpreter does not compute defaults unless needed |
function defaults_at_list (arg = rand (10000))
## just a simple operation
arg = arg +1;
endfunction
function defaults_at_cond (arg)
if (nargin == 0)
arg1 = rand (10000);
endif
## just a simple operation
arg = arg +1;
endfunction
t = cputime (); a = rand (10000); t_crea = cputime () - t
t = cputime (); defaults_at_list (a); t_list = cputime () - t
t = cputime (); defaults_at_cond (a); t_cond = cputime () - t
|
Function arguments (lazy copying)[edit]
When passing variables to a function, Octave will only make a copy of it is going to be modified. That is, unless the argument needs to be changed, the variable will be like a reference and take no extra memory or time to write.
Code: Looking at lazy copying |
function read_arg (arg)
x = arg(1);
endfunction
function modi_arg (arg)
arg(1) = 1;
endfunction
function chan_arg (arg)
arg = true;
endfunction
a = rand(10000);
t = cputime (); read_arg (a); t_read = cputime () -t ## takes NO time, since a copy of arg is never made
t = cputime (); modi_arg (a); t_read = cputime () -t ## takes some time since a copy of a will be made to be modified
t = cputime (); chan_arg (a); t_read = cputime () -t ## takes NO time since even though arg is modifed, it's not based on the original value
|
Global variables[edit]
Vectorization[edit]
It's well known that loops have bad performance in Octave. Vectorization of the code involves replacing them by vector operations. The Octave manual already has a good chapter on vectorization.