A few days ago I received the SAP Community Voice Newsletter in my email. I recommend you signing in SAP newsletters since they have really interesting articles about different topics. Anyway I found in the newsletter a really interesting article about improving ABAP code performance that I totally recommend to read:
How To Improve Your ABAP Code Performance
I want to give you a perfect example of how a bad ABAP code can completely destroy the performance of a program.
End-user complains about the overall performance of the system. As usual after checking with the user the performance issue is located on a few Z programs that he uses almost everyday.
As usual the system’s information is the following:
First of all I executed the transaction and I notice a high execution times in all the executions. Just to be clear a high execution time not always means a performance issue. As I explained before the perception of the user related to the execution time cannot be taken as an indicator for a performance issue on a SAP system. Users are human beings (most of the time) and nowadays humans are impatient…
Let’s start doing a performance trace of the program using ST12 transaction. I copied part of the data in the screenshot:
What is interesting here is that almost the whole execution time goes in the ABAP side. There is almost no database time which is usually strange. Of the calls side we can see that 2 reads to tables are consuming 66% and 33% of the total time. In this case it is clear that we have to take a look to both READ TABLE since there is something strange on them…
So I checked the ABAP code and I found the following READ TABLE on the code. The first thing that I saw was the SELECT INTO TABLE:
SELECT * FROM ztable INTO TABLE gt_alis_imputac.
Seeing this we already know that the SELECT * is not the best way to perform a SELECT. As the article stated the SELECT should be limited to the data we want/need because a SELECT * is inefficient. Anyway the performance issue is not in this SELECT since there was no execution time registered in the database side. I kept checking the code and I found a SORT for the gt_alis_imputac table:
SORT gt_alis_imputac BY bukrs
...
So this part of code should improve the performance of the program for the following READ TABLE done using this table. The READ table are the following ones:
READ TABLE gt_alis_imputac TRANSPORTING NO FIELDS
WITH KEY bukrs ...
READ TABLE gt_alis_imputac TRANSPORTING NO FIELDS
WITH KEY bukrs ...
So basically what happens here is that since the gt_alis_imputac table is defined as standard table then the read statements perform a linear seach til the end of the table. It really doesn’t matter if the person who created the program wrote a SORT before the READ TABLE, it just keep searching through the whole table.
Even worst, during the LOOP where the READ TABLE are performed the code modifies the gt_alis_imputac adding new records using an APPEND. This will cause that the sort order is destroyed after the first insert and impacting in the performance.
One easy action that we can do to improve this code is to use a BINARY SEARCH in each READ. The READ TABLE code would be something similar to this:
READ TABLE gt_alis_imputac TRANSPORTING NO FIELDS
WITH KEY bukrs ...
BINARY SEARCH.
Even better, if we declare the gt_alis_imputac as a SORTED TABLE we don’t need to perform a SORT of the table and we can skip the BINARY SEARCH. The READ statement automatically perform a binary search for sorted tables. The only problem will be using the same fields in the WITH KEY condition that the components of the table gt_alis_imputac.
Binary search is faster and more efficient than linear search. If we don’t write BINARY SEARCH then we are using the linear search which search one by one record from the table. For small tables is a good idea use a linear search since the performance won’t be impacted. But when we have big tables like this case the best practice is to use a BINARY SEARCH. This way what would happen is that the table will be divided in two equal parts. The search will check each part and decide in which of the part the element will be. Again, it will divide that part in two parts and do the same. This image explains it perfectly:
Notice the number of steps between a binary search and a linear search in a sorted table. About the adding new registers in a SORTED TABLE, if you use INSERT instead APPEND then the new registers will be added in the correct position.
I performed a new ST12 trace after improving the code:
Several things to remark here:
I think you get the idea of how a bad coding can impact greatly on the performance of the program. In this case the solution was really easy to implement and it didn’t’t take longer than 5 minutes.
Best coding practices and recommendations are created for a reason and it is quite common to ignore them. If you are a programmer please spend time improving your code. I know it is hard and you probably had better things to do but I promise it is completely worth it.
I hope you all survived the log4j Apocalypse and Christmas, hopefully you had a great…
I know it is being a while since I posted the last time. So far…
UPDATE 11/25/2020 Adobe released a new patch that solves the issue a few days ago:…
Good news for you fanatics of SAP GUI! SAP will release SAP GUI 7.70 in…
Quick update since I don't have a lot of time lately. During my 2019 job…
It's been a while since the last time I wrote an entry in my blog.…