可変次元配列（Varying-dimension arrays）

## 可変次元配列（Varying-dimension arrays）
最新の IBM i V7R4 で新たに追加された RPG 拡張の**可変次元配列**を試した。
[IBM Knowledge Center - 可変次元配列](https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/rzasd/vardimarray.htm)
#### 概略
何が追加されたかと言うと、これまでＲＰＧのＤ仕様書内で、静的に宣言されていた配列の要素数（※％ＡＬＯＣやＡＰＩでは動的に可能だった）をダイナミックで、宣言出来るという事。但し、要素数の最大数は、宣言に必要となっている。以下コーディング例

```RPG: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*                                                                         
```

```RPG: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`も変化する。

```CLP: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                                                           
```
```CLP: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|

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