Performance 有没有办法告诉我们哪些动词更有效
除了运行频闪,或者在作业结束时检查CPU使用情况之外,我还需要找出哪些COBOL动词更占用CPU吗?举个例子: 使用这个inspect语句会更有效吗(假设VARA是picx(10)) 还是写一个循环更好Performance 有没有办法告诉我们哪些动词更有效,performance,optimization,cobol,Performance,Optimization,Cobol,除了运行频闪,或者在作业结束时检查CPU使用情况之外,我还需要找出哪些COBOL动词更占用CPU吗?举个例子: 使用这个inspect语句会更有效吗(假设VARA是picx(10)) 还是写一个循环更好 PERFORM VARYING SUB1 FROM 1 BY 1 UNTIL SUB1 > 10 IF VARA(SUB1:1) = SPACE MOVE HIGH-VALUE TO VARA(SUB1:1) END-IF
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 for Z/OS 4.2.0编译器对事情进行了高度优化,因此一个好的起点是确保所有这些都已打开。既然你提到频闪,我想你有它。它会向您报告哪些代码部分占用了您的大部分时间,通常情况下,它并不是您所期望的,因此我会说运行这些报告,看看哪些动词会导致您出现问题,并尝试其他方法来完成同样的事情 在上述情况下,INSPECT语句应该变成一个非常快速的TR指令。但是,编译器可能能够通过展开该执行循环并将其转换为一系列非常快速的CLI/MVI语句,或者甚至是同一条TR指令来优化该执行循环
最有可能的是,这两个都不是你的问题。您还可以查看正在处理的文件,确保它们被正确地阻止和缓冲,以及所有这些,通常您可以在那里获得一些好的库来进行调整。在可能和可行的情况下,我们将使用我们商店的供应商实用程序,而不是编写COBOL。例如,排序实用程序通常针对I/O进行了高度优化,性能非常好 可维护性和效率之间可能存在权衡。有人认为COBOL比排序控制卡更容易理解和调试。我认为这取决于要完成的任务的性质 我的决策树是:
对于#2中的“合理”,一位同事在达到3个工作步骤时会放弃供应商的公用事业。我的上限更高。你自己的收益递减规则将取决于许多因素。这将使问题过于宽泛,无法处理所有问题,因此坚持
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有多种格式。上面包括两种格式,并使用文字、比喻常量和数据名。所有的检查结果都是一样的。生成的代码
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、Translate指令,它将彻底改变您可以用COBOL编写的任何代码,就性能而言
第四个执行一些工作(每次)来设置TR。第五个为运行时例程(IGZCIN1)建立参数,然后让该rip运行
所有这些都将打破你的循环。随着字段大小的扩展,情况会更糟
当然,如果你的领域很短,你有机会通过简单的IFs获胜
TR很快,但需要256字节的转换表
大多数情况下,INSPECT是非常快速的,而且,与所有动词一样,本质上知道所有事物的长度,因此不可能“off-bye-one”编写自己的代码
一些网站愚蠢地通过错误的思考(或者简单地说,没有思考)来“禁止”使用INSPECT。所有字符的计数都可能被认为是缓慢的,但为什么要使用它呢
现在,请表演。如果您想在循环查看每个字节的同时提高效率,请不要这样做:-)
你有“变化”,但什么是变化的?您正在查看10个字节。没有什么变化。哦,当然,它看起来更像是“代码”(来自其他语言),可以为您节省大量的打字工作量。按日付费:-)
(我还没有完成完整的格式化,因为VARA在那里,并且引用修改…)
然后,假设您必须测试超过一个字节的内容,并决定将OCCURS与索引BY一起使用,因为它“更高效”。然而,使用文字,甚至长度,你会对产生的曲折代码感兴趣。这是因为编译器在将索引与文本进行比较时必须“规范化”索引,它必须将其从位移转换为用于比较的条目号。通过松弛和使用变量,您通过使用索引(可能是全部,甚至更多)所获得的
要对INSPECT的两种类型和两种格式有更全面的了解,您需要生成“伪汇编程序”,了解它在做什么(至少在一般意义上),然后运行一些存根程序并实际比较所消耗的资源,然后打字,让自己确信差异在哪里
它不会一下子全部出现,这是一个持续的过程,然后,当您使用Enterprise COBOL V5+时,它会重新开始,因为一切都发生了变化:-)
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
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
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