[转] 如何高效地编写IDL代码 Tips & Thicks

适合所有IDL使用者好好看看:
Tips & Tricks for Efficient IDL Programming
尤其是3、5、9、10条:
3、Try to avoid IF statements within loops. When an IF statement appears in the middle of a loop with each element of an array in a conditional, the loop can be eliminated most of the time by using logical array expressions.

Slow:
for i = 0L, n_elements(data)-1L do $
if (data[i] le 30) then $
data[i] = 30

Faster:
dex = where(data le 30, count)
if (count gt 0) then data[dex] = 30

Even faster:
data = ((data gt 30) * data) + ((data le 30) * 30)

Fastest:
data = data > 30

5、Access large arrays by memory order. Arrays in IDL are column-major order. The important thing to remember is that IDL indexes arrays as [column, row]. The upper left-hand element of a matrix is considered to be [0,0]. This is the format used by FORTRAN, and is traditionally associated with image processing because it keeps all the elements of a single image scanline together. In contrast C and Visual Basic use row-major order and indexes its data as [row,column].

When an array is larger than or close to the working set size (the amount of physical memory available for the process) it should be accessed in memory order, meaning access it by accessing rows first.
for x = 0, 511 do for y = 0, 511 do arr[x, y] = ….
is very inefficient because to read the first column 250,000 bytes of data must be read into physical memory. This process must be repeated for each column, requiring the entire array to be read and written almost 512 times. By exchanging the two FOR loops the computing time can be reduced by a factor of 50:
for y = 0, 511 do for x = 0, 511 do arr[x, y] = ….

9. Use of the TEMPORARY function minimizes memory use when performing operations on large arrays. TEMPORARY reassigns to a new variable the memory referred to by its argument, deleting the old variable reference in the process (though the reassignment may be to a variable that reuses the original name). Assume that A is a large array. To add 1 to each element of A this is one coding option:
A = A + l
This statement creates a new array for the result of the addition and assigns the result to A before freeing the old allocation of A. Therefore, this operation needs 2*sizeof(A) of memory to perform the operation. The statement
A = temporary(A) + 1
needs no additional space.

10. Try not to use “*” for array indexing on the left hand side of a statement. Instead, use “0.” For instance, for the array
B = intarr(200, 200, 3)
it is much slower to use the following notation
B[*,*,1] = insertData
than to use
B[0,0,1] = insertData
The first notation is inefficient because the IDL interpreter will allocate/build a 200 x 200 long integer array of subscript indexes to substitute for the wildcard token. The latter notation does not need an array of subscripts; it performs direct copy to memory. (Note that ‘insertData’ must fit in the 200 x 200 x 2 memory space that defines the borders of the subarray that starts at ‘B[0,0,1]’ in order to avoid an array-out-of-bounds error.)

发表评论