home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
CLIPPER
/
CLIPTIPS.ZIP
/
ARRINF.ZIP
/
ARRINF.TXT
Wrap
Text File
|
1993-05-25
|
6KB
|
131 lines
Q: Is it more efficient to use one multi-dimensional array or
several single dimension arrays in a program. The array(s)
would be static and called at the top of the program.
A: [Don Caton]
Clipper does not have multi-dimensional arrays. If you're
thinking about something like aArray[1][2], that is NOT a
multi-dim array, the first element of 'aArray' just contains
another array. This is sometimes referred to as "nested"
or "ragged" arrays. Array elements in Clipper can contain
other arrays, but arrays can never have more than one
dimension.
This is not just a semantical difference, this is critically
important to understanding Clipper arrays. Given:
aArray1 := { 1, 2, NIL }
aArray2 := { 3, 4 }
aArray1[3] := aArray2
you can access the first element of aArray2 via 'aArray1[3][1]'
or 'aArray2[1]'; both expressions will retrieve the same data.
Likewise, assigning a new value into either expression will affect
the other, since they are looking at the same piece of data.
If you're familiar with C, you might think of 'aArray1' and
'aArray2' as containing pointers to their respective arrays,
and 'aArray1[3]' and 'aArray2' both contain the same pointer.
In terms of performance, it is definitely faster to access that
piece of data as 'aArray2[1]' rather than 'aArray1[3][1]'. The
first way only requires a single lookup as the reference
'aArray2' points to the desired array. The second way requires
'aArray1' to be located, then the data in the 3rd element is
obtained which is the reference to 'aArray2'. In other words,
the second method requires an additional indirection before the
desired data can be located.
The further "down" the desired array element is from the base
reference, the more indirections (and overhead) are required
to retrieve it. Something like aArray[1][3][5][6] would
require 3 array retrievals before obtaining the reference to
the array containing the 6th element you want. In general, this
isn't something to be overly concerned with but don't go making
your arrays unnecessarialy complex. If you had an array such as
the one above and you needed access to many of the elements in
the last array, you should do something like:
aTemp := aArray[1][3][5]
xElement := aTemp[6]
xElement := aTemp[7]
... etc.
This retrieves the array reference in aArray[1][3][5] into a
temporary variable, and eliminates the need for Clipper to
repeatedly start out at aArray1 and retrieve all the
intermediate array references.
As far as an array being STATIC, that has no bearing on
efficiency of accessing arrays, or any other data type
for that matter. STATIC is a visibility and lifetime issue.
Accessing STATIC (or LOCAL) data will be a bit more efficient
than something with a storage class of PUBLIC or PRIVATE, but
that's due to symbol table indirection and has nothing to do
with array access in particular.
Q: So which approach is faster:
aArray[1][5][3][6] := nVal1
aArray[1][5][3][7] := nVal2
aArray[1][5][3][8] := nVal3
or
aTemp := aArray[1][5][3]
aTemp[6] := nVal1
aTemp[7] := nVal2
aTemp[8] := nVal3
A: [Don Caton]
The second method is always going to be faster, for the simple
reason that arrays in Clipper are strictly single-dimensional.
When you access something like 'aArray[1][5][3][6]', internally
Clipper has to access 4 discrete arrays from the object memory
system in order to return the desired element.
The first array is the one referred to by 'aArray'. When that is
accessed, the first element is retrieved which also contains an
array reference. That array is accessed and its fifth element
is retrieved which again contains an array reference. That array
is accessed and its third element is retrieved which yet again,
contains an array reference. Finally, that array is accessed
and the sixth element is retrieved and assigned into the variable.
Any or all of those arrays could be in memory, in ems or on disk.
The worst case would be that all four of those arrays were
swapped out to disk and each one would have to be brought back in,
one at a time.
Just because an array contains references to other arrays,
they are still completely discrete units of data. Doing
something like 'aArray[1][5][3][6]' doesn't access all
the arrays in one operation, there's simply no way to know
what any of those elements contain until all the relevant arrays
and elements are accessed. Element 3 of the third array might not
contain an array reference for example, so the expression
would fail at the fourth internal array access.
If Clipper's arrays were truly multidimensional they would also be
symmetrical, and any element in any dimension could be accessed
simply by calculating the proper offset. For example, in Foxbase
the array element 'x(2,2)' is actually the fourth element
in array 'x'. In Clipper, the absolute location of an element
in a multi-subscriped array reference cannot be calculated
in one shot because the expression doesn't refer to a single data
entity.
It's always going to be faster therefore to obtain the reference
to the "lowest" array you need to access and hold on to that
if you need to access more than one of its elements.
For similar reasons, it's always faster to assign an object's
instance variable to a local variable when you need to access
it more than once. That way you eliminate the repeated message
lookup and array retrieval (objects are really arrays at the
internal level).
###