Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > 3e60ff9d4d6f58c8fbd17208f14089fa > files > 95

octave-doc-3.2.3-3mdv2010.0.i586.rpm

<html lang="en">
<head>
<title>Coding Tips - Untitled</title>
<meta http-equiv="Content-Type" content="text/html">
<meta name="description" content="Untitled">
<meta name="generator" content="makeinfo 4.13">
<link title="Top" rel="start" href="index.html#Top">
<link rel="up" href="Tips-and-Standards.html#Tips-and-Standards" title="Tips and Standards">
<link rel="prev" href="Style-Tips.html#Style-Tips" title="Style Tips">
<link rel="next" href="Comment-Tips.html#Comment-Tips" title="Comment Tips">
<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
<meta http-equiv="Content-Style-Type" content="text/css">
<style type="text/css"><!--
  pre.display { font-family:inherit }
  pre.format  { font-family:inherit }
  pre.smalldisplay { font-family:inherit; font-size:smaller }
  pre.smallformat  { font-family:inherit; font-size:smaller }
  pre.smallexample { font-size:smaller }
  pre.smalllisp    { font-size:smaller }
  span.sc    { font-variant:small-caps }
  span.roman { font-family:serif; font-weight:normal; } 
  span.sansserif { font-family:sans-serif; font-weight:normal; } 
--></style>
</head>
<body>
<div class="node">
<a name="Coding-Tips"></a>
<p>
Next:&nbsp;<a rel="next" accesskey="n" href="Comment-Tips.html#Comment-Tips">Comment Tips</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="Style-Tips.html#Style-Tips">Style Tips</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="Tips-and-Standards.html#Tips-and-Standards">Tips and Standards</a>
<hr>
</div>

<h3 class="section">C.2 Tips for Making Code Run Faster.</h3>

<p><a name="index-execution-speed-2508"></a><a name="index-speedups-2509"></a>
Here are some ways of improving the execution speed of Octave programs.

     <ul>
<li>Vectorize loops. For instance, rather than
     <pre class="example">          for i = 1:n-1
            a(i) = b(i+1) - b(i);
          endfor
</pre>
     <p>write

     <pre class="example">          a = b(2:n) - b(1:n-1);
</pre>
     <p>This is especially important for loops with "cheap" bodies. Often it suffices to vectorize
just the innermost loop to get acceptable performance. A general rule of thumb is that the
"order" of the vectorized body should be greater or equal to the "order" of the enclosing loop.

     <li>Use built-in and library functions if possible. Built-in and compiled functions are very fast. 
Even with a m-file library function, chances are good that it is already optimized, or will be
optimized more in a future release.

     <li>Avoid computing costly intermediate results multiple times. Octave currently
does not eliminate common subexpressions.

     <li>Be aware of lazy copies (copy-on-write). When a copy of an object
is created, the data is not immediately copied, but rather shared. The actual
copying is postponed until the copied data needs to be modified. For example:

     <pre class="example">          a = zeros (1000); # create a 1000x1000 matrix
          b = a; # no copying done here
          b(1) = 1; # copying done here
</pre>
     <p>Lazy copying applies to whole Octave objects such as matrices, cells, struct,
and also individual cell or struct elements (not array elements).

     <p>Additionally, index expressions also use lazy copying when Octave can determine
that the indexed portion is contiguous in memory. For example:

     <pre class="example">          a = zeros (1000); # create a 1000x1000 matrix
          b = a(:,10:100); # no copying done here
          b = a(10:100,:); # copying done here
</pre>
     <p>This applies to arrays (matrices), cell arrays, and structs indexed using (). 
Index expressions generating cs-lists can also benefit of shallow copying
in some cases. In particular, when <var>a</var> is a struct array, expressions like
<code>{a.x}, {a(:,2).x}</code> will use lazy copying, so that data can be shared
between a struct array and a cell array.

     <p>Most indexing expressions do not live longer than their `parent' objects. 
In rare cases, however, a lazily copied slice outlasts its parent, in which
case it becomes orphaned, still occupying unnecessarily more memory than needed. 
To provide a remedy working in most real cases,
Octave checks for orphaned lazy slices at certain situations, when a value
is stored into a "permanent" location, such as a named variable or cell or
struct element, and possibly economizes them. For example

     <pre class="example">          a = zeros (1000); # create a 1000x1000 matrix
          b = a(:,10:100); # lazy slice
          a = []; # the original a array is still allocated
          c{1} = b; # b is reallocated at this point
</pre>
     <li>Avoid deep recursion. Function calls to m-file functions carry a relatively significant overhead,
so rewriting a recursion as a loop often helps. Also, note that the maximum level of recursion is
limited.

     <li>Avoid resizing matrices unnecessarily. When building a single result
matrix from a series of calculations, set the size of the result matrix
first, then insert values into it.  Write

     <pre class="example">          result = zeros (big_n, big_m)
          for i = over:and_over
            r1 = ...
            r2 = ...
            result (r1, r2) = new_value ();
          endfor
</pre>
     <p class="noindent">instead of

     <pre class="example">          result = [];
          for i = ever:and_ever
            result = [ result, new_value() ];
          endfor
</pre>
     <p>Sometimes the number of items can't be computed in advance, and stack-like operations
are needed. When elements are being repeatedly inserted at/removed from the end of an
array, Octave detects it as stack usage and attempts to use a smarter memory management
strategy preallocating the array in bigger chunks. Likewise works for cell and
struct arrays.

     <pre class="example">          a = [];
          while (condition)
            ...
            a(end+1) = value; # "push" operation
            ...
            a(end) = []; # "pop" operation
            ...
          endwhile
</pre>
     <li>Use <code>cellfun</code> intelligently. The <code>cellfun</code> function is a useful tool
for avoiding loops. See <a href="Processing-Data-in-Cell-Arrays.html#Processing-Data-in-Cell-Arrays">Processing Data in Cell Arrays</a>. 
<code>cellfun</code> is often use with anonymous function handles; however, calling
an anonymous function involves an overhead quite comparable to the overhead
of an m-file function. Passing a handle to a built-in function is faster,
because the interpreter is not involved in the internal loop. For example:

     <pre class="example">          a = {...}
          v = cellfun (@(x) det(x), a); # compute determinants
          v = cellfun (@det, a); # faster
</pre>
     <li>Avoid calling <code>eval</code> or <code>feval</code> excessively, because
they require Octave to parse input or look up the name of a function in
the symbol table.

     <p>If you are using <code>eval</code> as an exception handling mechanism and not
because you need to execute some arbitrary text, use the <code>try</code>
statement instead.  See <a href="The-_003ccode_003etry_003c_002fcode_003e-Statement.html#The-_003ccode_003etry_003c_002fcode_003e-Statement">The <code>try</code> Statement</a>.

     <li>If you are calling lots of functions but none of them will need to
change during your run, set the variable
<code>ignore_function_time_stamp</code> to <code>"all"</code> so that Octave doesn't
waste a lot of time checking to see if you have updated your function
files. 
</ul>

   </body></html>