comparison doc/interpreter/tips.txi @ 11997:5530fe42c83b release-3-2-x

update coding tips
author Jaroslav Hajek <highegg@gmail.com>
date Thu, 18 Jun 2009 07:09:17 +0200
parents f69e27ff396a
children d85a43495faa
comparison
equal deleted inserted replaced
11996:8c2a1c876c2c 11997:5530fe42c83b
83 83
84 Here are some ways of improving the execution speed of Octave programs. 84 Here are some ways of improving the execution speed of Octave programs.
85 85
86 @itemize @bullet 86 @itemize @bullet
87 @item 87 @item
88 Avoid looping wherever possible. 88 Vectorize loops. For instance, rather than
89 89 @example
90 @item 90 for i = 1:n-1
91 Use iteration rather than recursion whenever possible. 91 a(i) = b(i+1) - b(i);
92 Function calls are slow in Octave. 92 endfor
93 93 @end example
94 @item 94
95 Avoid resizing matrices unnecessarily. When building a single result 95 write
96
97 @example
98 a = b(2:n) - b(1:n-1);
99 @end example
100
101 This is especially important for loops with "cheap" bodies. Often it suffices to vectorize
102 just the innermost loop to get acceptable performance. A general rule of thumb is that the
103 "order" of the vectorized body should be greater or equal to the "order" of the enclosing loop.
104
105 @item
106 Use built-in and library functions if possible. Built-in and compiled functions are very fast.
107 Even with a m-file library function, chances are good that it is already optimized, or will be
108 optimized more in a future release.
109
110 @item
111 Avoid computing costly intermediate results multiple times. Octave currently
112 does not eliminate common subexpressions.
113
114 @item
115 Be aware of lazy copies (copy-on-write). When a copy of an object
116 is created, the data is not immediately copied, but rather shared. The actual
117 copying is postponed until the copied data needs to be modified. For example:
118
119 @example
120 a = zeros (1000); # create a 1000x1000 matrix
121 b = a; # no copying done here
122 b(1) = 1; # copying done here
123 @end example
124
125 Lazy copying applies to whole Octave objects such as matrices, cells, struct,
126 and also individual cell or struct elements (not array elements).
127
128 Additionally, index expressions also use lazy copying when Octave can determine
129 that the indexed portion is contiguous in memory. For example:
130
131 @example
132 a = zeros (1000); # create a 1000x1000 matrix
133 b = a(:,10:100); # no copying done here
134 b = a(10:100,:); # copying done here
135 @end example
136
137 This applies to arrays (matrices), cell arrays, and structs indexed using ().
138 Index expressions generating cs-lists can also benefit of shallow copying
139 in some cases. In particular, when @var{a} is a struct array, expressions like
140 @code{@{a.x@}, @{a(:,2).x@}} will use lazy copying, so that data can be shared
141 between a struct array and a cell array.
142
143 Most indexing expressions do not live longer than their `parent' objects.
144 In rare cases, however, a lazily copied slice outlasts its parent, in which
145 case it becomes orphaned, still occupying unnecessarily more memory than needed.
146 To provide a remedy working in most real cases,
147 Octave checks for orphaned lazy slices at certain situations, when a value
148 is stored into a "permanent" location, such as a named variable or cell or
149 struct element, and possibly economizes them. For example
150
151 @example
152 a = zeros (1000); # create a 1000x1000 matrix
153 b = a(:,10:100); # lazy slice
154 a = []; # the original a array is still allocated
155 c@{1@} = b; # b is reallocated at this point
156 @end example
157
158 @item
159 Avoid deep recursion. Function calls to m-file functions carry a relatively significant overhead,
160 so rewriting a recursion as a loop often helps. Also, note that the maximum level of recursion is
161 limited.
162
163 @item
164 Avoid resizing matrices unnecessarily. When building a single result
96 matrix from a series of calculations, set the size of the result matrix 165 matrix from a series of calculations, set the size of the result matrix
97 first, then insert values into it. Write 166 first, then insert values into it. Write
98 167
99 @example 168 @example
100 @group 169 @group
117 result = [ result, new_value() ]; 186 result = [ result, new_value() ];
118 endfor 187 endfor
119 @end group 188 @end group
120 @end example 189 @end example
121 190
122 @item 191 Sometimes the number of items can't be computed in advance, and stack-like operations
123 Avoid calling @code{eval} or @code{feval} whenever possible, because 192 are needed. When elements are being repeatedly inserted at/removed from the end of an
193 array, Octave detects it as stack usage and attempts to use a smarter memory management
194 strategy preallocating the array in bigger chunks. Likewise works for cell and
195 struct arrays.
196
197 @example
198 a = [];
199 while (condition)
200 @dots{}
201 a(end+1) = value; # "push" operation
202 @dots{}
203 a(end) = []; # "pop" operation
204 @dots{}
205 endwhile
206 @end example
207
208 @item
209 Use @code{cellfun} intelligently. The @code{cellfun} function is a useful tool
210 for avoiding loops. @xref{Processing Data in Cell Arrays}.
211 @code{cellfun} is often use with anonymous function handles; however, calling
212 an anonymous function involves an overhead quite comparable to the overhead
213 of an m-file function. Passing a handle to a built-in function is faster,
214 because the interpreter is not involved in the internal loop. For example:
215
216 @example
217 a = @{@dots{}@}
218 v = cellfun (@@(x) det(x), a); # compute determinants
219 v = cellfun (@@det, a); # faster
220 @end example
221
222 @item
223 Avoid calling @code{eval} or @code{feval} excessively, because
124 they require Octave to parse input or look up the name of a function in 224 they require Octave to parse input or look up the name of a function in
125 the symbol table. 225 the symbol table.
126 226
127 If you are using @code{eval} as an exception handling mechanism and not 227 If you are using @code{eval} as an exception handling mechanism and not
128 because you need to execute some arbitrary text, use the @code{try} 228 because you need to execute some arbitrary text, use the @code{try}