有没有办法判断哪些动词更有效率

Is there a way to tell what verbs are more efficient

除了 运行 闪光灯,或在工作结束时检查 CPU 用法之外,我还能找出哪些 COBOL 动词更 CPU 密集吗?举个例子:

使用这个检查语句会更有效吗(假设 VARA 是 PIC X(10) )

INSPECT VARA REPLACING ALL SPACE 
                       BY  HIGH-VALUE

还是写一个循环会更好

PERFORM VARYING SUB1
        FROM    1 BY 1
        UNTIL   SUB1 > 10
   IF VARA(SUB1:1) = SPACE
      MOVE HIGH-VALUE TO VARA(SUB1:1)
   END-IF
END-PERFORM

背景

我有一些程序正在处理包含数百万条记录的文件,但一些作业的执行情况不如我们预期。我正在尝试分析较长的 运行 作业并找到非侵入性的方法来加速它们(如上面更改循环检查的示例)。唯一的问题是,我实际上不知道什么实际上更有效率。我们不想为了改变而改变,但如果我能以某种方式告诉我们改变会提高性能,我们几乎肯定会这样做。

我正在使用 Z/OS 2.01.00 和 COBOL Z/OS 4.2.0

编译器对事物进行了高度优化,因此一个好的起点是确保所有这些都已打开。既然你提到了 Strobe,我就假设你有它。它会给你报告哪些代码部分占用了你的大部分时间,通常,它不是你期望的,所以我会说 运行 这些报告,看看哪些动词导致你出现问题并尝试其他方法来完成同样的事情。

在上面的例子中,INSPECT 语句应该变成一个非常快的 TR 指令。但是编译器可能能够通过展开该 PERFORM 循环并将其转换为一系列非常快速的 CLI/MVI 语句,甚至可能是相同的 TR 指令来优化该 PERFORM 循环。

很有可能,这些都不是您的问题。您还可以查看您正在处理的文件并确保它们被正确阻止和缓冲等等,通常您可以在那里获得一些不错的调整费用。

在可能和可行的情况下,我们将使用我们商店的供应商实用程序而不是编写 COBOL。例如,SORT 实用程序通常针对 I/O 进行了高度优化,并且性能非常好。

可能需要在可维护性和效率之间进行权衡。有人认为 COBOL 比 SORT 控制卡更容易理解和调试。我认为这取决于要完成的任务的性质。

我的决策树是:

  1. 尝试使用供应商实用程序实现目标
  2. 如果无法合理地做到这一点,则尝试通过自定义来实现目标 使用现有通用子程序的代码
  3. 编写自定义代码,尝试创建通用子例程 可以在类似的未来情况下使用

对于 #2 中的 "reasonably",一位同事在完成 3 个工作步骤后会放弃供应商实用程序。我的极限更高。您自己的递减规则 returns 将取决于许多因素。

这会使问题过于宽泛,无法解决所有问题,因此请坚持使用 INSPECT 和您的 PERFORM 示例。

   WORKING-STORAGE SECTION. 
   01  THE-STRING                          PIC X(50). 
   01  A-HIGH-VALUE                        PIC X VALUE HIGH-VALUES.
   01  A-SPACE                             PIC X VALUE SPACE. 

   PROCEDURE DIVISION. 
       INSPECT THE-STRING 
         REPLACING                  ALL SPACE 
                                    BY HIGH-VALUE 
       INSPECT THE-STRING 
         CONVERTING                 ' ' 
                                    TO X'FF' 
       INSPECT THE-STRING 
         CONVERTING                 HIGH-VALUE 
                                    TO HIGH-VALUE 
       INSPECT THE-STRING 
         REPLACING                  ALL A-HIGH-VALUE 
                                    BY A-HIGH-VALUE 
       INSPECT THE-STRING 
         CONVERTING                 A-HIGH-VALUE 
                                    TO A-HIGH-VALUE 
       GOBACK 
       . 

INSPECT 有多种格式。上面包括两种格式,并使用文字、图形常量和数据名称。所有 INSPECT 产生相同的结果。生成的代码...

000010  INSPECT                                                                                                  
   000544  DC31 8000 A12C          TR    0(50,8),300(10)         THE-STRING                        PGMLIT AT +292

000011  INSPECT                                                                                                  
   00054A  DC31 8000 A12C          TR    0(50,8),300(10)         THE-STRING                        PGMLIT AT +292

000012  INSPECT                                                                                                  
   000550  DC31 8000 A12C          TR    0(50,8),300(10)         THE-STRING                        PGMLIT AT +292

000013  INSPECT                                                                                                  
   000556  D2FF D100 A02C          MVC   256(256,13),44(10)      TS2=0                             PGMLIT AT +36 
   00055C  41E0 D100               LA    14,256(0,13)            TS2=0                                           
   000560  1BFF                    SR    15,15                                                                   
   000562  BFF1 8038               ICM   15,1,56(8)              A-HIGH-VALUE                                    
   000566  1AFE                    AR    15,14                                                                   
   000568  D200 F000 8040          MVC   0(1,15),64(8)           A-SPACE                                         
   00056E  DC31 8000 D100          TR    0(50,8),256(13)         THE-STRING                        TS2=0         

000014  INSPECT                                                                                                  
   000574  5820 905C               L     2,92(0,9)               TGTFIXD+92                                      
   000578  58F0 2044               L     15,68(0,2)              V(IGZCIN1 )                                     
   00057C  4110 A296               LA    1,662(0,10)             PGMLIT AT +654                                  
   000580  0DEF                    BASR  14,15                                                                   

可以看出,前三个示例(编译器知道要更改的值以及它们要更改的内容)都生成一个简单的 TR,翻译,指令,这绝对会撕掉任何东西的面孔就性能而言,您可以使用 COBOL 进行编码。

第四次(每次)做一些工作来为 TR 进行设置。第五个为 运行 时间例程 (IGZCIN1) 建立参数,然后让它消失。

所有这些都会打败你的循环。随着字段的大小扩展,更是如此。

当然,如果你的领域很短,你有机会使用简单的 IFs 获胜。

TR 速度很快,但确实需要 256 字节的转换 table。

大多数情况下 INSPECT 非常快速,并且与所有动词一样,本质上知道所有内容的长度,因此 "off-bye-one" 没有机会自己编写代码。

一些站点愚蠢地"ban"通过错误的思维(或者简单地说,没有思考)使用 INSPECT。对所有字符进行计数可以被认为很慢,但为什么要使用它?

现在开始表演。如果您想在循环查看每个字节的同时提高效率,请不要那样做:-)

PERFORM VARYING SUB1
        FROM    1 BY 1
        UNTIL   SUB1 > 10
   IF VARA(SUB1:1) = SPACE
      MOVE HIGH-VALUE TO VARA(SUB1:1)
   END-IF
END-PERFORM

你有 "VARYING",但有什么不同?您正在查看 10 个字节。那里没有变数。哦,当然,它看起来更像 "code"(来自其他语言)并且可以节省您的输入工作量。每天付费 :-)

MOVE ZERO TO SUB1
PERFORM LENGTH OF VARA TIMES
   ADD 1 TO SUB1 
   IF VARA ( SUB1 : 1 ) = SPACE
      MOVE HIGH-VALUE TO VARA ( SUB1 : 1 )
   END-IF
END-PERFORM

(我没有做完整的格式化,因为有VARA,引用修改...)

然后,假设您必须测试超过一个字节的内容,并决定将 OCCURS 与 INDEXED BY 一起使用,因为它是 "more efficient"。然而,使用字面值,甚至使用 LENGTH OF,您会对生成的曲折代码感兴趣。这是因为编译器在将其与文字进行比较时必须 "normalise" 一个索引,它必须将其从位移转换为条目号以进行比较。使用 INDEXED BY 所获得的收益(也许是全部,甚至更多)是通过松弛和使用 VARYING 来实现的。

为了更全面地了解 INSPECT 的几种格式的几种类型,您需要生成 "pseudo assembler",了解它在做什么(至少在一般意义上是这样) 然后 运行 一些存根程序并实际比较消耗的资源,并键入以说服自己在哪里消耗了任何差异。

它不会一下子全部实现,它是一个持续的过程,然后,当您进入 Enterprise COBOL V5+ 时,它会重新开始,因为一切都变了:-)