home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1993 #2 / Image.iso / clipper / arrinf.zip / ARRINF.TXT
Text File  |  1993-05-25  |  6KB  |  131 lines

  1. Q:  Is it more efficient to use one multi-dimensional array or
  2.     several single dimension arrays in a program. The array(s)
  3.     would be static and called at the top of the program.
  4.  
  5. A:  [Don Caton]
  6.  
  7.     Clipper does not have multi-dimensional arrays. If you're
  8.     thinking about something like aArray[1][2], that is NOT a
  9.     multi-dim array, the first element of 'aArray' just contains
  10.     another array.  This is sometimes referred to as "nested"
  11.     or "ragged" arrays.  Array elements in Clipper can contain
  12.     other arrays, but arrays can never have more than one
  13.     dimension.
  14.  
  15.     This is not just a semantical difference, this is critically
  16.     important to understanding Clipper arrays.  Given:
  17.  
  18.          aArray1    := { 1, 2, NIL }
  19.          aArray2    := { 3, 4 }
  20.          aArray1[3] := aArray2
  21.  
  22.     you can access the first element of aArray2 via 'aArray1[3][1]'
  23.     or 'aArray2[1]'; both expressions will retrieve the same data.
  24.     Likewise, assigning a new value into either expression will affect
  25.     the other, since they are looking at the same piece of data.
  26.     
  27.     If you're familiar with C, you might think of 'aArray1' and
  28.     'aArray2' as containing pointers to their respective arrays,
  29.     and 'aArray1[3]' and 'aArray2' both contain the same pointer.
  30.  
  31.     In terms of performance, it is definitely faster to access that
  32.     piece of data as 'aArray2[1]' rather than 'aArray1[3][1]'.  The
  33.     first way only requires a single lookup as the reference
  34.     'aArray2' points to the desired array.  The second way requires
  35.     'aArray1' to be located, then the data in the 3rd element is
  36.     obtained which is the reference to 'aArray2'.  In other words,
  37.     the second method requires an additional indirection before the
  38.     desired data can be located.
  39.  
  40.     The further "down" the desired array element is from the base
  41.     reference, the more indirections (and overhead) are required
  42.     to retrieve it.  Something like aArray[1][3][5][6] would
  43.     require 3 array retrievals before obtaining the reference to
  44.     the array containing the 6th element you want.  In general, this
  45.     isn't something to be overly concerned with but don't go making
  46.     your arrays unnecessarialy complex.  If you had an array such as
  47.     the one above and you needed access to many of the elements in
  48.     the last array, you should do something like:
  49.  
  50.          aTemp := aArray[1][3][5]
  51.          xElement := aTemp[6]
  52.          xElement := aTemp[7]
  53.          ... etc.
  54.  
  55.     This retrieves the array reference in aArray[1][3][5] into a
  56.     temporary variable, and eliminates the need for Clipper to
  57.     repeatedly start out at aArray1 and retrieve all the
  58.     intermediate array references.
  59.  
  60.     As far as an array being STATIC, that has no bearing on
  61.     efficiency of accessing arrays, or any other data type
  62.     for that matter.  STATIC is a visibility and lifetime issue.
  63.     Accessing STATIC (or LOCAL) data will be a bit more efficient
  64.     than something with a storage class of PUBLIC or PRIVATE, but
  65.     that's due to symbol table indirection and has nothing to do
  66.     with array access in particular.
  67.  
  68. Q:  So which approach is faster:
  69.  
  70.          aArray[1][5][3][6] := nVal1
  71.          aArray[1][5][3][7] := nVal2
  72.          aArray[1][5][3][8] := nVal3
  73.  
  74.     or
  75.  
  76.          aTemp    := aArray[1][5][3]
  77.          aTemp[6] := nVal1
  78.          aTemp[7] := nVal2
  79.          aTemp[8] := nVal3
  80.  
  81. A:  [Don Caton]
  82.  
  83.     The second method is always going to be faster, for the simple
  84.     reason that arrays in Clipper are strictly single-dimensional.
  85.     When you access something like 'aArray[1][5][3][6]', internally
  86.     Clipper has to access 4 discrete arrays from the object memory
  87.     system in order to return the desired element.
  88.  
  89.     The first array is the one referred to by 'aArray'.  When that is
  90.     accessed, the first element is retrieved which also contains an
  91.     array reference.  That array is accessed and its fifth element
  92.     is retrieved which again contains an array reference.  That array
  93.     is accessed and its third element is retrieved which yet again,
  94.     contains an array reference.  Finally, that array is accessed
  95.     and the sixth element is retrieved and assigned into the variable.
  96.  
  97.     Any or all of those arrays could be in memory, in ems or on disk.
  98.     The worst case would be that all four of those arrays were
  99.     swapped out to disk and each one would have to be brought back in,
  100.     one at a time.
  101.  
  102.     Just because an array contains references to other arrays,
  103.     they are still completely discrete units of data.  Doing
  104.     something like 'aArray[1][5][3][6]' doesn't access all
  105.     the arrays in one operation, there's simply no way to know
  106.     what any of those elements contain until all the relevant arrays
  107.     and elements are accessed.  Element 3 of the third array might not
  108.     contain an array reference for example, so the expression
  109.     would fail at the fourth internal array access.
  110.  
  111.     If Clipper's arrays were truly multidimensional they would also be
  112.     symmetrical, and any element in any dimension could be accessed
  113.     simply by calculating the proper offset.  For example, in Foxbase
  114.     the array element 'x(2,2)' is actually the fourth element
  115.     in array 'x'.  In Clipper, the absolute location of an element
  116.     in a multi-subscriped array reference cannot be calculated
  117.     in one shot because the expression doesn't refer to a single data
  118.     entity.
  119.  
  120.     It's always going to be faster therefore to obtain the reference
  121.     to the "lowest" array you need to access and hold on to that
  122.     if you need to access more than one of its elements.
  123.  
  124.     For similar reasons, it's always faster to assign an object's
  125.     instance variable to a local variable when you need to access
  126.     it more than once.  That way you eliminate the repeated message
  127.     lookup and array retrieval (objects are really arrays at the
  128.     internal level).
  129.  
  130.  
  131.                                   ###