Mercurial > hg > octave-lyh
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} |