Optimising Caching Arrays - Part I

Many times we want to store frequently used information in arrays,
in this case Well Name and Well I.D.:

D @WNM            S             40    DIM(50)       
D @WID            S             15    DIM(50)       


The code that follows is as found in the wild:


To load the array: 


C*                                                                     
C*                                                                     
C*    Add Well Name and Well ID to arrays if not already there.        
C*                                                                     
C                   IF        I2URRF  <> *BLANK  AND                   
C                             I2$WNM  <> *BLANK                        
C*                                                                     
C                   Z-ADD     1             $W                3 0      
C     I2$WNM        LOOKUP    @WNM($W)                               71
C     *IN71         IFEQ      *OFF                                     
C*                                                                     
C                   Z-ADD     1             $W                3 0      
C     *BLANK        LOOKUP    @WNM($W)                               71
C     *IN71         IFEQ      *ON                                      
C     $W            ANDLE     50                                       
C*                                                                     
C                   MOVEL     I2$WNM        @WNM($W)                   
C                   MOVEL     I2URRF        @WID($W)                   
C*                                                                     
C                   ENDIF                                              
C                   ENDIF                                              
C                   ENDIF           


To do a look up against the array:


C                   Z-ADD     1             $W                3 0       
C     I2$WNM        LOOKUP    @WNM($W)                               71 
C     *IN71         IFEQ      *ON                                       
C                   MOVEL     @WID($W)      I2URRF                      
C                   ENDIF                                               


The area for improvement for both the load and the lookup lies in the fact that
in a sparsely loaded array, we are doing a lot of comparisons against blank entries.


A more efficient way is if we keep track of the first *unused* array element, 
and place the value we are looking for in that element. If $WW is a variable
containing the first unused array element (e.g. $WW = 1 for an empty array)
our lookup would look like:

C                   Z-ADD     1             $W                3 0       
C                   MOVEL     I2$WNM        @WNM($WW)                   
C     I2$WNM        LOOKUP    @WNM($W)                               71 
C     $W            IFNE      $WW                                       
C                   MOVEL     @WID($W)      I2URRF                      
C                   ENDIF                                               
C                   ENDIF      


In an array that is sparsely populated we only have to do $WW comparisons (where
$WW is the number of used array elements plus one) instead of %Elem(@WNM) comparisons.


The code to load the array (when $WW is initialised to 1) looks like:


C*                                                                     
C*                                                                     
C*    Add Well Name and Well ID to arrays if not already there.        
C*                                                                     
C                   IF        I2URRF  <> *BLANK  AND                   
C                             I2$WNM  <> *BLANK  AND                   
C                             $WW     <  50                            
C*                                                                     
C                   Z-ADD     1             $W                3 0      
C                   MOVEL     I2$WNM        @WNM($WW)                  
C     I2$WNM        LOOKUP    @WNM($W)                               71
C     $WW           IFEQ      $W                                       
C*                                                                     
C                   MOVEL     I2URRF        @WID($W)                   
C                   ADD       1             $WW               3 0      
C*                                                                     
C                   ENDIF                                              
C                   ENDIF                                                                                                                          


Valid HTML 3.2! Creative Commons License

BrilligWare/ chris@pando.org / revised February 2008