可変次元配列(Varying-dimension arrays)

最新の IBM i V7R4 で新たに追加された RPG 拡張の可変次元配列を試した。
IBM Knowledge Center - 可変次元配列

概略

何が追加されたかと言うと、これまでRPGのD仕様書内で、静的に宣言されていた配列の要素数(※%ALOCやAPIでは動的に可能だった)をダイナミックで、宣言出来るという事。但し、要素数の最大数は、宣言に必要となっている。以下コーディング例

V7R4001R.rpgle(可変次元配列)
H DATEDIT(*YMD)                                                    
H DFTACTGRP(*NO) ACTGRP(*NEW)                                      
H OPTION(*NOUNREF)                                                 
H BNDDIR('QC2LE')                                                  
D*--------------------------------------------------------         
D VAR_ARRAY1      S              9S 0 DIM(*VAR  : 100  )           
D AUTO_ARRAY1     S              1S 0 DIM(*AUTO : 16773103 )       
D*                                                                 
D IX              S              9S 0 INZ                          
D TS_S            S               Z                                
D TS_E            S               Z                                
D EXEC_T          S             15S12                              
C*- ***************************************************************
C*- * MAIN ROUTINE                                               **
C*- ***************************************************************```
C*                                                                 
C                   CALLP     PRINT ( '---- PROGRAM START ----')   
C* 配列数の設定                                  
C                   EVAL      %ELEM(VAR_ARRAY1 ) = 25              
C*                                                                 
C                   MONITOR                                        
C*                                                                 
C                   FOR       IX = 1 TO 26                         
C                   EVAL      VAR_ARRAY1(IX) = IX                  
C                   ENDFOR                                         
C* (26)の指標エラーを想定
C                   ON-ERROR  *ALL                                 
C                   CALLP     PRINT ( '> INDEX ERROR = '           
C                                      + %EDITC(IX :'3') )         
C                   ENDMON                                         
C*                                                                 
C                   EVAL      TS_S  = %TIMESTAMP()                 
C                   CALLP     PRINT ( '> *** BENTCH  START ***'    
C                                                + %CHAR( TS_S ) ) 
C* 要素数の自動拡張
C     1             DO        16773103      IX                             
C                   EVAL      AUTO_ARRAY1(*NEXT) = 1                       
C                   ENDDO                                                  
C*                                                                         
C                   EVAL      TS_E  = %TIMESTAMP()                         
C                   EVAL      EXEC_T  = %DIFF(TS_E : TS_S : *SECONDS :12)  
C                   CALLP     PRINT ( '> EXEC TIME = ' + %CHAR( EXEC_T ) ) 
C                   CALLP     PRINT ( '> *** BENTCH  END   ***'            
C                                                + %CHAR( TS_E ) )         
C*                                                                         
C                   CALLP     PRINT ( '> AUTO ELEMNTS = '                  
C                                    + %EDITC(%ELEM(AUTO_ARRAY1 ) :'3') )  
C*                                                                         
C                   CALLP     PRINT ( '---- PROGRAM END   ----')           
C                   SETON                                        LR        
C                   RETURN                                                 
C*                                                                         
V7R4002R.rpgle(静的配列)
H DATEDIT(*YMD)                                                     
H DFTACTGRP(*NO) ACTGRP(*NEW)                                       
H OPTION(*NOUNREF)                                                  
H BNDDIR('QC2LE')                                                   
D*--------------------------------------------------------          
D VAR_ARRAY1      S              9S 0 DIM(100  )                    
D AUTO_ARRAY1     S              1S 0 DIM(16773103)                 
D*                                                                  
D IX              S              9S 0 INZ                           
D TS_S            S               Z                                 
D TS_E            S               Z                                 
D EXEC_T          S             15S12                               
C*- *************************************************************** 
C*- * MAIN ROUTINE                                               ** 
C*- *************************************************************** 
C*                                                                  
C                   CALLP     PRINT ( '---- PROGRAM START ----')    
C*                                                                  
C                   FOR       IX = 1 TO 26                                 
C                   EVAL      VAR_ARRAY1(IX) = IX                          
C                   ENDFOR                                                 
C*                                                                         
C                   EVAL      TS_S  = %TIMESTAMP()                         
C                   CALLP     PRINT ( '> *** BENTCH  START ***'            
C                                                + %CHAR( TS_S ) )         
C*                                                                         
C     1             DO        16773103      IX                             
C                   EVAL      AUTO_ARRAY1(IX   ) = 1                       
C                   ENDDO                                                  
C*                                                                         
C                   EVAL      TS_E  = %TIMESTAMP()                         
C                   EVAL      EXEC_T  = %DIFF(TS_E : TS_S : *SECONDS :12)  
C                   CALLP     PRINT ( '> EXEC TIME = ' + %CHAR( EXEC_T ) ) 
C                   CALLP     PRINT ( '> *** BENTCH  END   ***'            
C                                                + %CHAR( TS_E ) )         
C*                                                                         
C                   CALLP     PRINT ( '---- PROGRAM END   ----')     
C                   SETON                                        LR  
C                   RETURN                                           

静的記憶域の比較

DSPPGMで静的記憶域を比較すると、可変次元配列では最大数を変更しても、Static storage sizeに変化は見られない。これは、実行時に記憶域を確保していると思われる。
一方、静的配列では、指標数や要素のバイト数に応じてStatic storage sizeも変化する。

DSPPGM(V7R4001R可変次元配列)
                          Display Program Information                           
                                                                 Display 1 of 7 
 Program  . . . . . . . :   V7R4001R      Library  . . . . . . . :        
 Owner  . . . . . . . . :   USHIDAY                                             
 Program attribute  . . :   RPGLE                                               
 Detail . . . . . . . . :   *BASIC                                              

 Program statistics:                                                            
   Number of parameters . . . . . . . . . . . . . :   0            255          
   Associated space size (decompressed) . . . . . :   4096                      
   Static storage size  . . . . . . . . . . . . . :   3392                      
   Allow static storage reinitialization  . . . . :   *NO                       
   Program size . . . . . . . . . . . . . . . . . :   155648                    
   Program state  . . . . . . . . . . . . . . . . :   *USER                     
   Program domain . . . . . . . . . . . . . . . . :   *USER                     
   Release program created on . . . . . . . . . . :   V7R4M0                    
   Release program created for  . . . . . . . . . :   V7R4M0                    
   Earliest release program can run . . . . . . . :   V7R4M0                    
                                                                        More... 
 Press Enter to continue.                                                       

 F3=Exit   F12=Cancel                                                           
DSPPGM(V7R4002R静的配列)
                          Display Program Information                           
                                                                 Display 1 of 7 
 Program  . . . . . . . :   V7R4002R      Library  . . . . . . . : 
 Owner  . . . . . . . . :   USHIDAY                                             
 Program attribute  . . :   RPGLE                                               
 Detail . . . . . . . . :   *BASIC                                              

 Program statistics:                                                            
   Number of parameters . . . . . . . . . . . . . :   0            255          
   Associated space size (decompressed) . . . . . :   4096                      
   Static storage size  . . . . . . . . . . . . . :   16776944                  
   Allow static storage reinitialization  . . . . :   *NO                       
   Program size . . . . . . . . . . . . . . . . . :   135168                    
   Program state  . . . . . . . . . . . . . . . . :   *USER                     
   Program domain . . . . . . . . . . . . . . . . :   *USER                     
   Release program created on . . . . . . . . . . :   V7R4M0                    
   Release program created for  . . . . . . . . . :   V7R4M0                    
   Earliest release program can run . . . . . . . :   V7R4M0                    
                                                                        More... 
 Press Enter to continue.                                                       

 F3=Exit   F12=Cancel                                                           

ベンチマーク

可変次元配列では、静的記憶域を確保していないため、実行時の記憶域確保回数が増えるにつれてスコアに影響すると思われるので、前述のプログラムで比較した。
番外として、確保回数を255回に減らした場合もテストした。実行時の配列拡張回数を減らすとスコアに影響した為、この点を考慮してアプリケーションの構築をすると良いと思われる。

タイプ データ型 配列最大要素数 サイズ拡張回数 平均スコア (sec)
可変次元配列 S 1 1,6773,103 1,6773,103 1.626000
静的配列 S 1 1,6773,103 1,6773,103 0.796000
【番外】可変次元配列 A 65,535 255 255 0.033000
【番外】可変次元配列 S 1 1,6773,103 1,024 0.001000

考察

「ようやくRPGも出来るようになったかぁ」と思いつつも、煩雑な記述を使うことを考えると地味に嬉しい。早く、どのバージョンでも使用できる状況にならないかしら。