Wednesday, November 1, 2023

Testing the new save compression ZLIB

After applying the latest round of CUM PTFs to a partition with IBM i 7.4 I noticed that the new save compression algorithm, ZLIB, is available. I was surprised as I was under the impression that ZLIB was only available for IBM i 7.5 . There is no mention of ZLIB in the help for the Save Objects command, SAVOBJ, data compression parameter's help. Was this an oversight by IBM introducing something that was not compatible 7.4? This made me want to test it to see if it worked in 7.4, and if it did how much were the savings compared to the other types of data compression.

I have before compared the savings I could get with the various compression algorithms. Now I could compare them all to the new ZLIB.

I had not bothered to test ZLIB on the partitions I use with 7.5, as I do not have a large library I can test with and I cannot ensure that others will not start a job that will slow down the partition.

Fortunately I know of a 7.4 partition which is rarely used by anyone, except me. Therefore, it would be extremely unlikely anyone would do something that could impact my testing.

For this experiment I will save all the objects in a large-ish library to a save file using the Save Objects command. I would repeat the SAVOBJ with the following types of compression in the data compression parameter, DTACPR:

  1. *ZLIB
  2. *HIGH
  3. *MEDIUM
  4. *LOW

I will call the library LIBRARY1. All the objects in the library occupy 181,188,345,856 bytes. The save file itself occupies 24,576 byes.

The SAVOBJ command I will use is:

  SAVOBJ OBJ(*ALL) 
           LIB(LIBRARY1)
           DEV(*SAVF)
           SAVF(MYLIB/TESTSAVF)
           DTACPR(XXXX)  

The XXXX is where the various compression types would be.

I created a program that would perform the save for each save algorithm in turn. It would calculate the time taken for the save to be performed, and after the program had completed I would retrieve the size of the save file using SQL.

I am only going to show part of the program. This part is for the save with ZLIB:

01  **free
02  dcl-s StartTime timestamp ;
03  dcl-s EndTime timestamp ;
04  dcl-s Library varchar(10) inz('LIBRARY1') ;
05  dcl-s Compression varchar(10) ;
06  dcl-s Command varchar(100) ;
07  dcl-s DiffMins packed(15) ;
08  dcl-s DiffHours packed(15) ;

09  dcl-c SavObj1 'SAVOBJ OBJ(*ALL) LIB(' ;
10  dcl-c SavObj2 ') DEV(*SAVF) SAVF(MYLIB/TESTSAVF) DTACPR(' ;

11  exec sql CALL QSYS2.QCMDEXC('CLRSAVF MYLIB/TESTSAVF') ;

12  Compression = '*ZLIB' ;

13  Command = SavObj1 + Library + SavObj2 + Compression + ')' ;

14  StartTime = %timestamp() ;

15  exec sql CALL QSYS2.QCMDEXC(:Command) ;

16  EndTime = %timestamp() ;

17  exec sql SET :DiffMins = TIMESTAMPDIFF(4, CHAR(:EndTime - :StartTime)) ;
18  exec sql SET :DiffHours = TIMESTAMPDIFF(8, CHAR(:EndTime - :StartTime)) ;

19  exec sql INSERT INTO MYLIB.OUTFILE VALUES(:Compression, :Library,
                  :StartTime, :EndTime, :DiffMins, :DiffHours) ;  

Line 1: In 2023 we should all be using totally free RPG.

Lines 2 – 8: The definitions of the variables I will be using in the program. I will not bother to describe what each one is as I think their names give you their purpose.

Lines 9 and 10: Constants that contain the SAVOBJ command's parameters.

Line 11: I use the QCMDEXC Procedure to clear the save file I will be saving to.

Line 12: This "run" is for the ZLIB compression algorithm.

Line 13: I am "building" the SAVOBJ command as a string, and placing that in the Command variable. I do this combining the first constant with the name of the library in the Library variable, then adding the second constant, lastly adding the compression type's name followed by a closing parenthesis ( ) ).

Line 14: Capture the timestamp, before I start the save.

Line 15: Perform the SAVOBJ using the QCMDEXC SQL procedure.

Line 16: Capture the timestamp.

Line 17 and 18: Calculating the difference between the two timestamps using the TIMESTAMPDIFF SQL function. The first difference is in minutes and the second is in hour. The differences are in whole minutes or hours, no part of those units.

Line 19: I insert a row into an output file, OUTFILE, so I have all the details from this type of save.

After compiling and running the program I would retrieve the size of the save file using the OBJECT_STATISTICS SQL Table function:

01  SELECT OBJSIZE
02    FROM TABLE(QSYS2.OBJECT_STATISTICS('MYFILE',
03                                       '*FILE',
04                                       'TESTSAVF'))

Line 1: OBJSIZE is the file of the object in bytes.

When I had run a save for all of these compression algorithms I could see the results:

Save
algorithm
Duration
in minutes
Duration
in hours
Save file
size
*ZLIB 236 3 3,474,513,100
*HIGH 349 5 4,248,467,046
*MEDIUM 145 2 51,622,494,208
*LOW 35 0 106,559,512,576

I was surprised how much faster and smaller ZLIB was compared to the high compression. As I expected it was not faster than the medium or low.

I will be using ZLIB for saves as a smaller save file will take less time to be FTP-ed to other partitions.

 

This article was written for IBM i 7.4.

2 comments:

  1. As a sidenote, to get the big boost of the ZLIB compression you need Power 10 processors running in Power 10 mode to be able to use the NX accelerator.

    ReplyDelete
  2. Just circled back to this. Weekly job transferring data between LPARs. 1.1 Gb. Used to take 2.5 hours end to end with compression set to default *YES. Switched to *ZLIB. No increase in save time(some saves even decreased). 63% reduction in SAVF size and over an hour and a quarter saved on transmission time. Power 10 on 7.5.

    ReplyDelete

To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.

Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.