I was recently asked whether Java performance on a PC was adequate for processing SMF data. More generally, people have been sceptical about Java performance. So, I thought why not borrow the idea from the Java 1 Billion Row Challenge, and write a Java program to see how fast you can produce a report on 1 billion CICS transactions using the EasySMF Java API?
The test is to read CICS monitoring facility SMF data and produce a report showing:
- transaction counts,
- maximum, minimum and average elapsed times
- average and total USRCPUT
grouped by APPLID and transaction ID, for 1 billion CICS transactions.
- The CICS SMF records are compressed using CICS compression.
- The SMF records are not sorted or pre-processed for the report.
Watch the video, or read more detail below…
Input Data
The first problem was I didn’t have enough sample data for 1 billion transactions, so I wrote a small program to build a file containing 1 billion transactions. It reads an input file and writes the data to a new file repeatedly, until the new file contains records for the required number of transactions.
That means the input contains repeated data, but that shouldn’t influence the run time as long as the initial file is reasonably large.
The resulting file with 1 billion transactions was 586 GB.
The program to generate the data is available here: GenerateInput.java
PC Hardware
The PC used to run the test was a Windows PC, with an i5-14400 processor and 1TB Crucial P310 M.2 SSD. This is a reasonable midrange PC, nothing extreme or expensive.
The Program
Entries in the original 1 billion row challenge used some pretty advanced techniques to get the winning time down to around 1.5 seconds.
However, with this program I’m trying to keep it simple and use standard techniques that should be familiar to any Java programmer, and at least readable to people familiar with similarly structured languages like C/C++.
The program uses a class to accumulate data about each applid/transaction combination. The entries are stored in a HashMap with a Java record containing the applid and transaction name as the key. This provides very fast access as the data is processed.
The CICS records require a dictionary to access locate the fields in the SMF record. A file containing the CICS dictionary SMF records is read before the main data file.
View the program source on Github (only 134 lines):
Results
The program produced the report from 1 billion CICS transactions in 20 minutes 17 seconds. Some statistics from the run:
- Read SMF data: 492 MB/s
- Decompress the compressed portion of the record: 420 MB/s
- Decompressed data size: 3.1 TB
- Process decompressed data: 2.6 GB/s
Most of the CPU time was spent doing the CICS SMF data decompression.
How to make it faster?
On a PC, the simple answer is multithreading. This PC has 10 cores (6 performance cores, 4 efficiency cores) and can run 16 threads simultaneously. The CICS data decompression in particular will benefit from multiple threads.
The program can be converted to use Java Streams, specifying parallel() to divide the work across multiple threads.
Note that this might not be a good idea on z/OS. Java by default will attempt to create enough threads to use all the processors on the system – which is probably not desirable on the mainframe. On the other hand, it could work OK in a discretionary service class and will probably be limited by I/O speed anyway so YMMV.
Here’s the parallel version of the program on Github:
Java Streams provides methods to do the accumulation independently and merge the results from each thread at the end. That avoids the problem of synchronizing updates between threads.
However, for this test, I elected to minimize the changes from the original version and just moved the processing to a forEach block. That means that any updates to shared data in the forEach block need to be synchronized between threads. Change required were:
- Transaction counts were changed to use the LongAdder class.
- The HashMap was changed to a ConcurrentHashMap
- The add method in the TransactionData class was made synchronized.
In theory, accumulating independently and merging at the end should be faster because it avoids having to synchronize threads. However, most of the time here is spent decompressing data so any gain is probably insignificant.
Results
The parallel run finished in 7 minutes 18 seconds. Statistics:
- Read SMF data: 1.3 GB/s
- Decompress the compressed portion of the record: 1.1 GB/s
- Process decompressed data: 7.2 GB/s
Reporting on 1 billion transactions in 7 minutes 18 seconds seems pretty good. That’s over 2 million transactions per second. The times are pretty linear with transaction count, so e.g. if you have only 100 million transactions it should run in less than a minute.
Even faster?
According to the Windows performance monitor, the parallel run didn’t max out the disk or the CPU. In theory the SSD is capable of more than 1.3 GB/s so there might be more performance to be found.
At some point the I/O is being processed sequentially, so I suspect that is the bottleneck. Perhaps it would be faster if there were multiple files e.g. if the SMF data was divided by CICS region or system and I/O could be processed to multiple files in parallel.
A subject for future investigation, perhaps.
Try it on your data
Contact us at info@blackhillsoftware.com for a free trial. Let us know what reports you would like and we can add them to the samples.
Notes
- This runs fast enough that I/O is potentially the bottleneck. On z/OS, I have found that zEDC compression for SMF data can significantly improve I/O speed. Using zEDC and CICS SMF record compression might be better than zEDC alone. See some tests here.
- This is 100% Java so it is zIIP eligible on z/OS. This is a particular advantage if the general purpose CPs run at less than full speed.
- For CICS records, most of the time is spent decompressing the records. It is reasonably easy to modify the program to produce multiple different reports from the same pass of the data, which means that additional reports cost almost zero CPU or elapsed time.
- EasySMF can read data using the z/OSMF Dataset and Files REST API. You can run a Java program on the PC and access the mainframe SMF data using a https connection.
- AI is pretty good at writing Java, and Java type safety in the EasySMF API helps keep it on track with the SMF data so it’s very feasible to use AI to help write SMF reports.



