Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
emanuel_klenner
Active Participant
We have all done it, written a piece of code that seems pretty cool in the development environment and when it hits a customer with sufficient data volume, it turns into a slow crawling snail.

That means back to the drawing board and evaluating different approaches for the code.
We have to take runtime measurements to compare the results and make an educated guess of which approach might be the best.

The ABAP development environment offers lots of nice tools to do runtime measurements, e.g.
the ST05 trace, the SAT runtime measurements, the SQL monitor, etc.

Instead of using the tools, I just want to have something built into my code that gives me a quick
overview of how I am doing. Maybe even better, I want to deliver built in measurements that
normally lie dormant and only wake up when I want them to.

We can use the ABAP statement GET RUN TIME or GET TIMESTAMP and do our own calculations
to find how long it is taking. Throw in a WRITE statement for good measure and we got this.

That is all fine but it is not very elegant and just a tad cumbersome.

I would like to introduce you to an alternative approach for runtime measurements.
Most of the work is done by the class CL_PMMO_RTM and the accesses to the class are
hidden in ABAP macros in order to keep the coding footprint that has to do with measuring
and displaying measurements to a minimum. The macros are defined in the INCLUDE report
RPMMO_RTM_MACROS.

The class and the report are delivered with SAP S/4 HANA on premise release 1909.
For older releases, including ECC there is the class CL_EASY_RTM and the demo report
R_EASY_RTM_DEMO.

Let's take a little sample program and examine what is involved in this approach.
I just want to compare a standard internal table read vs. a sorted table read.
REPORT zema_easy_rtm_1.

* macro definitions for runtime measurements
INCLUDE rpmmo_rtm_macros.

PARAMETERS p_num TYPE i DEFAULT 10000.

CLASS lcl_demo_rtm DEFINITION.
PUBLIC SECTION.
DATA gt_tstc TYPE STANDARD TABLE OF tstc.
DATA gt_tstct TYPE STANDARD TABLE OF tstct.

METHODS main.
METHODS select_tcodes_and_texts.
METHODS standard_table_access.
METHODS sorted_table_access.
ENDCLASS.

CLASS lcl_demo_rtm IMPLEMENTATION.

METHOD main.
select_tcodes_and_texts( ).

standard_table_access( ).
sorted_table_access( ).

display_rtm. "macro for displaying the runtime measurement results
ENDMETHOD.

METHOD select_tcodes_and_texts.
SELECT * FROM tstc INTO TABLE gt_tstc UP TO p_num ROWS.

CHECK sy-subrc IS INITIAL.

SELECT * FROM tstct INTO TABLE gt_tstct
FOR ALL ENTRIES IN gt_tstc
WHERE sprsl = sy-langu
AND tcode = gt_tstc-tcode.

ENDMETHOD.

METHOD standard_table_access.
declare_rtm. "declares variable LO_RTM TYPE CL_PMMO_RTM.

LOOP AT gt_tstc INTO DATA(ls_tstc).
start_rtm 'Standard access to table TSTCT'. "Create an instance of LO_RTM and start the measurement

READ TABLE gt_tstct WITH KEY tcode = ls_tstc-tcode
INTO DATA(ls_tstct).

stop_rtm. "Stop the measurement
ENDLOOP.

ENDMETHOD.

METHOD sorted_table_access.
DATA lt_tstct_sort TYPE SORTED TABLE OF tstct WITH UNIQUE KEY sprsl tcode.

declare_rtm. "declares variable LO_RTM TYPE CL_PMMO_RTM.

lt_tstct_sort = gt_tstct.

LOOP AT gt_tstc INTO DATA(ls_tstc).
start_rtm 'Sorted access to table TSTCT'. "Create an instance of LO_RTM and start the measurement

READ TABLE lt_tstct_sort WITH KEY sprsl = sy-langu tcode = ls_tstc-tcode
INTO DATA(ls_tstct).

stop_rtm. "Stop the measurement
ENDLOOP.

ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.
NEW lcl_demo_rtm( )->main( ).

You need the include RPMMO_RTM_MACROS in the data declaration section of a program or in the macro definition area of a global class.
INCLUDE rpmmo_rtm_macros.

Here is a small snapshot of what is contained in the report:
DEFINE declare_rtm.
DATA lo_rtm TYPE REF TO cl_pmmo_rtm.
DATA lo_rtm1 TYPE REF TO cl_pmmo_rtm.
END-OF-DEFINITION.

DEFINE start_rtm.
CREATE OBJECT lo_rtm
EXPORTING
iv_title = &1.
END-OF-DEFINITION.

DEFINE stop_rtm.
IF lo_rtm IS NOT INITIAL.
lo_rtm->end( ).
ENDIF.
END-OF-DEFINITION.

To start measuring a section of code you need the declaration and the start macro.
    declare_rtm.   

LOOP AT gt_tstc INTO DATA(ls_tstc).
start_rtm 'Standard access to table TSTCT'.

When you are done with a particular measurement, call the stop macro.
stop_rtm.

When all measurements are done, display the results:
display_rtm.

Here is the output:


Notice, that the text field you specify together with the start_rtm macro is used to aggregate the
measurements in the output list. You can expand the list to see the individual measurements:



From the output list you can see that the access using a sorted table is much faster than an access
with a standard table. I also cheated a little bit because I did not include a measurement for the sorting of the table. Maybe you can try that and then tell me if the sorted access method is still the
better deal?!

I mentioned dormant measurements before that only wake up when desired. How is that achieved?
start_rtm_grp 'Standard access to table TSTCT'.

Just a slight variation in the macro usage. The macro START_RTM_GRP only instantiates the CL_PMMO_RTM class if the check point group PMMO_RTM has been activated via transaction SAAB.



Save the activation:




Now your measurements are only active for the specified period. Afterwards they will become dormant again.

There are a lot more features available in the CL_PMMO_RTM class, e.g. saving measurements to the database and analyzing them via a separate transaction. Comparing multiple measurements is also a possibility.

I will cover these features in a future blog.

I hope that you are sufficiently intrigued by this approach and will give it a try.
If you have comments or questions, please let me know.
7 Comments