Skip to Content
Technical Articles
Author's profile photo Emanuel Klenner

ABAP Runtime Measurements Made Easy

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.

Assigned Tags

      5 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      Hi, Emanuel! Thank you for sharing!

      I've searched for some information on this class CL_PMMO_RTM and it seems to belong to specific functionality Project Manufacturing Management & Optimization (PMMO). With that in mind, is it advisable for SAP customers to use this class in the scenarios not related to PMMO?

      I'm asking because just recently there was a blog post where another class was suggested but SAP issued a note that it is meant only for a specific scenario. I'm concerned that this class might as well end up with a similar note.

      Also, more generally, why aren't the classes that have generally useful functionality delivered as part of ABAP (or some other, not application-specific component)? In the customer projects, if we identify some class/feature that could have broader application, we make an effort to place it into a different package. Is there no such process in SAP internally?

      Author's profile photo Emanuel Klenner
      Emanuel Klenner
      Blog Post Author

      Hi Jelena,

      Very valid points. This class is mostly used in Project Manufacturing Management and Optimization but it is intended for multi purpose use. It can be used by other applications.

      ABAP basis development has very different goals and backlogs then application development
      and they often simply do not have the time to deliver something in the standard that an
      application component has come up with.

      Sometimes functionality that originated by an application (best example is the ALV) will be backported to the basis layer/packages but I don't see this happening here.

      Best regards,
      Emanuel

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      Thank you for a reply, Emanuel!

      Author's profile photo Laurens Deprost
      Laurens Deprost

      Thanks for sharing, Emmanuel.
      This seems like an elegant implementation for runtime measurements indeed.

      I want to deliver built in measurements that normally lie dormant and only wake up when I want them to.

      I love this approach.
      I'm gonna play around with the class/include. I'm thinking of including the checkpoint group logic in the generic report classes used at clients so that each report has measurements if desired.

      Author's profile photo Emanuel Klenner
      Emanuel Klenner
      Blog Post Author

      Hi Laurens,

      I am glad to hear that you like this approach.
      Good like implementing it for your report classes.
      Let me know how you fare and if there are ideas
      for improvements.

      Emanuel