Skip to Content

ABAP Runtime Analysis of Transformations & DTPs


                   We develop various  ABAP Programs, Customized T-codes and Function Modules in our projects as per our requirements. To fine tune our developments, we have to check “What are the Runtimes of our ABAP Programs, Customized T-codes and Customized Function Modules?”

SAP has given us a nice t-code SE30 for this purpose. You can check the runtimes of Standard (ABAP programs, T-codes and FMs)

                      This blog is not to test the data volume handling through transformation and DTPs. Because data volume is not fixed, today you do some analysis by based on some amount of volume and you arrive some figures in the statistics from SE30. But the data load may increase/ future. So then today’s analysis will be invalidated. That’s exactly I have proposed to test the ABAP coding part only before loading data through transformations/DTPs.

                    I am going to demonstrate How to do Runtime Analysis of Transformations and DTPs.. in this blog.

Step 1: Go to the Transformation —> Extras from the top menu —> Display Generated Program, then you see the screen like below.

                  Trans runtime.JPG

Step 2 : Copy the technical name(whole string) of the generated report

Step 3 : Go to SE30 t-code and paste it in Program text box  and press execute like below


This will calculate Runtimes in three categories. You can check them by pressing Evaluate button in above screen shot.

Finally you can make a note of various Runtimes by observing the below screen.


Result : The above  Program has spent majority of time in ABAP(Presentation), 11.5% at Database level(Datsbase Systems like MSSQL, Oracle etc) and 7.7% at System level(Application)

Similarly, you can copy the string from DTP–>Extras–>Generated Program Filter and check the runtimes by following above steps

Note : Suppose you are analyzing some FM / t-code, when you press Execute as per Step 3, you will literally get into the execution of that FM / t-code and you see the result–>Then you need to press Back button on top to reach SE30 screen –>You will see Runtime Analysis of so and so FM / t-code has been finished on the Status bar at bottom of the screen. Finally you can click on Evaluation button to see various runtimes

You must be Logged on to comment or reply to a post.
  • Hi Suman,

    Thanks to you. I learnt something new today. Looks like BW has a lot of ‘easter eggs’ like these waiting to be discovered 🙂

    Nice document.



  • Hi Suman,

    Sorry but I think that this way does not work at all..

    If you look at this generated program, you will see that only have methods and forms, when you try to execute in SE38, for example, the abap code will not be called.. using the transaction SE30 in this way will have the same effect

    • Hi Paulo,

      This is an auto generated program by the system. You cannot assess individual routines and field level routines individually. There is no privilege available as of now. The only way is to take the auto generated program and do analysis in SE30 as I mentioned. I have tested almost all of my transformations and DTPs in this fashion. I observed different variations in “Evaluation tab”. This gave me an idea on How best are my Transformations and DTPs in terms of performance. You cannot execute this generated program in SE38 as this is not executable program, just a generated program.

      You can check the runtimes(processings of all datapackages) of DTPs in DTP monitor itself. Here in my blog, I talk about Runtime Anlaysis in three places(ABAP,Database and System). Please try to understand the difference between the two.

      Please test some of your Transformations and DTPs by using my blog to understand the reality.



      • Hi Suman,

        When I talked about using SE38 my intention was to say that using SE30 will not call any routine of the generated program too, I mean, in this approach seems that the custom code (start or end routine in the transformation for example) will not be evaluated in the graph.



        • Hi Paul,

          I have analyzed my Transformation Generated Program thoroughly. It considers all routines which are part of the transformation like Start/End routines and field routines too.

          I am 100% correct. If you want, you can analyze your generated program, to see all the logics of your routines are considered while evaluating in Graphs. You can debug in Se38. I am just wondering on ,How couldn’t you see the routine logics in the generated program in SE38? I am able to view them. Just look at your generated program to observe all your field routines ans start/end routines will be considered.

          I repeat the graph does not give dummy figure. It evaluates all routines inside and finally give you the graph.

          I have tested everything before making the blog.



          • Hi Suman,

            Yeah I am able to see routine logic in the generated program, that is not the point.

            Maybe I am facing a different behavior in SE30, but in the graph screen, when I press the button Hit List (F5), it shows me something like that:


            Runtime analysis

            Submit Report GP33D5W03QZJP0B164OBEY72NKY

            Program GP33D5W03QZJP0B164OBEY72NKY

            Load Report GP33D5W03QZJP0B164OBEY72NKY

            Event SYSTEM-EXIT

            Perform not found BEFORE_EVENT

            This screen shows the trace of the runtime analysis, including the gross time that is used in the graph.

            It is possible to see more detailed information selecting all options in Display Filter (Shift+F2)

            In my test, this trace does not show any perform, call function or call method that exists in start/end/field routines.

            I am not saying that you are wrong, maybe in your tests the custom code is in the Hit List, I believe that this post can be very helpful for many people, but I get a different result and I was trying to figure out why.



          • Hi Paul,

            I am able to see “Cal Method” and “Call Function” in my Hit list. Can you try with any other transformations? This is something strange in your case..

            Thanks to start working on my doc.



          • Hi Suman,

            Can you show us your “Hit list” please?

            What happens when you run the same transformation program twice? the result changes?



          • HI Paulo,

            I am not in front of PC now. I cannot show you my “Hit List”. Please read my whole blog once again and try with User/service if you want to test data. Otherwise, just try with execute.



          • Hi Paulo,

            While making the blog, i have tested at least 10 -15 transformations/DTPs in my system. I got different Graphs for all. This proves that it does not give you dummy graphs. SE30 is a standard t-code which can be used for runtime analysis. I don’t know what’s wrong with your analysis? If you think it is a trash, it is up to you. You may simply ignore the blog and try to find out other way and share with me. Then, i will discard this blog and follow yours. No hurt feelings for me. I am open..Please read a new paragraph which i have added.



      • Hi Suman,

        Its really a good way to find about the runtimes. However, as per Paulo, is it true that the generated programs of transformations, when evaluated, will not consider routines involved in it?

        Please do update me whether it also consider the runtime of routines involved when displaying the results for the transformations.

        Thanks & regards,

        Mohammed Naveed.

        • Hi Mohammed,

          I have analyzed my Transformation Generated Program thoroughly. It will consider all routines which are part of the transformation like Start/End routines and field routines too.

          I am 100% correct. If you want, you can analyze your generated program, to see all the logics of your routines are considered while evaluating in Graphs.



  • Hi Suman,

    Thanks for sharing.

    I have a doubt how does it claculates the runtime. Does it executes the DTP when you give the generated program name for tranformation over there because transformation would only be read when DTP is ran.

    I have not tested the same before putting this questions. May be i would do that later.


    • After every creation of Trans/DTP, the system it self creates a generated program after activating them. This run time is all about ABAP, database and System as per your design. This will not run the DTP while testing this. This will indicate you where all(ABAP, Datbase and System) levels, the more time your object(Trans/DTP) spends..Before finalizing your Trans and DTP routines, it’s advisable to test as per the blog.

      • Hi Suman,


        I understands that generated program would be created automatically once trans/dtp are activated.I need to know how will it tell without running the DTP the areas which needs improvement if any.Is it going to test based upon previous DTP logs may be from stats.

        Although i would test the same.



  • Hi Suman,

    the described procedure to analyse the runtime of a BW transformation or DTP is not working – at least on BW 730. The reason is, that if you execute the generated program of the transformation in SM30, the transformation is run without any records. The program does not select the data on its own, but needs a dtp to provide the records for the transformation.

    To get the SM30 work with a dtp/transformation you have to use the “Schedule for User/Service” option.

    Best regards,


    • Hi Daniel,

      You have misunderstood the blog. My procedure is to find out the runtimes in three categories before loading data. This procedure is just to test the ABAP codes performance but not to test the data volume. Your point has already been discussed in other above comments by others.

      I am ware that “Schedule for User/Service” is for your purpose. Please review your comments once again.



      • Hi Suman,

        if you run the generated program in SE30 directly the coding of the transformation (start-, end-routine, etc.) is not executed. So, the figures produced by SE30 are quite useless.

        I have tested the procedure with several transformations and I always got the same result. Actually I should have got different results, depending on the transformation routines.

        Best regards,


        • OK. It’s not helpful to you. Please ignore the blog. I repeat, i have tested at least 10-15 cases, i got different results. Only then, i made this blog. Thanks for your straight forward review.

  • Hi Suman,

    Thanks for sharing very good document.

    I checked one of the transformations. Data load to DSO is taking 50 minutes to load 1.5 lakhs records. So i checked in SM30 and please find the below screenshot. I just want to reduce the data load time. As of now, from the graph, it is showing 80% in data base level. Please suggest how to reduce the loading time.


    • Thanks for writing to me. Unless we see your code, we cannot really suggest the best methods. Please post it..

      Have you used any semantic groups in DTP?

      • Hi Suman,

        Sorry for the late reply. Herewith I am attaching the code written in the End Routine. The above snapshot belongs to this Code. Please have a look.

        *$*$ begin of global – insert your declaration only below this line  *-*

            … “insert your code here


              BEGIN OF ty_stat,

                /bic/zemplye   TYPE /bic/oizemplye,

                /bic/zcustsls  TYPE /bic/oizcustsls,

                /bic/zotlkvgr1 TYPE /bic/oizotlkvgr1,

                /bic/zacustsls TYPE /bic/oizacustsls,

                /bic/zicustsls TYPE /bic/oizicustsls,

                /bic/zsdate    TYPE dats,

                /bic/zedate    TYPE dats,

              END OF ty_stat.


              it_stat          TYPE TABLE OF ty_stat,

              it_stat_dup      TYPE TABLE OF ty_stat,

              wa_stat          TYPE ty_stat,

              it_stat2         TYPE TABLE OF ty_stat,

              wa_stat2         TYPE ty_stat.

        *$*$ end of global – insert your declaration only before this line   *-*




                  source_segid             type rstran_segid

                  source_record            type sytabix


                  record_new               type sytabix.




                  request                  type rsrequest

                  datapackid               type rsdatapid


                  monitor                  type rstr_ty_t_monitors


                  RESULT_PACKAGE              type _ty_t_TG_1






                  i_th_fields_outbound         TYPE rstran_t_field_inv

                  i_r_selset_outbound          TYPE REF TO cl_rsmds_set

                  i_is_main_selection          TYPE rs_bool

                  i_r_selset_outbound_complete TYPE REF TO cl_rsmds_set

                  i_r_universe_inbound         TYPE REF TO cl_rsmds_universe


                  c_th_fields_inbound          TYPE rstran_t_field_inv

                  c_r_selset_inbound           TYPE REF TO cl_rsmds_set

                  c_exact                      TYPE rs_bool.

        ENDCLASS.                    “routine DEFINITION

        *$*$ begin of 2nd part global – insert your code only below this line  *

        … “insert your code here

        *$*$ end of 2nd part global – insert your code only before this line   *


        *       CLASS routine IMPLEMENTATION




        CLASS lcl_transform IMPLEMENTATION.


        *       Method end_routine


        *       Calculation of result package via end routine

        *       Note: Update of target fields depends on rule assignment in

        *       transformation editor. Only fields that have a rule assigned,

        *       are updated to the data target.


        *   <-> result package


          METHOD end_routine.

        *=== Segments ===


              <RESULT_FIELDS>    TYPE _ty_s_TG_1.


              MONITOR_REC     TYPE rstmonitor.

        *$*$ begin of routine – insert your code only below this line        *-*

            … “insert your code here


             result1 TYPE TABLE OF _ty_s_tg_1 ,

             v_salesman TYPE /bic/oizemplye,

             v_month(6) TYPE c,

             st_month(6) TYPE c,

             en_month(6) TYPE c,

             v_count(12) TYPE c VALUE 0.

            result1[] = RESULT_PACKAGE[].

            TYPES : BEGIN OF ty_outlet,

                    lv_outlet     TYPE /bic/oizcust_sal,

                    lv_outtype    TYPE /bic/oiyotlt_typ,

                    lv_outsubtype TYPE /bic/oiygrp_otlt,

                   END OF ty_outlet.

            DATA : it_outlet TYPE STANDARD TABLE OF ty_outlet,

                   wa_outlet TYPE ty_outlet.


            APPEND LINES OF it_stat2 TO it_stat_dup.

            SORT it_stat_dup BY /bic/zcustsls.

            DELETE ADJACENT DUPLICATES FROM it_stat_dup COMPARING /bic/zcustsls.

            IF it_stat_dup IS NOT INITIAL.





                FROM /bic/pzcust_sal

                INTO TABLE it_outlet

                FOR ALL ENTRIES IN it_stat_dup

                WHERE /bic/zcust_sal = it_stat_dup-/bic/zcustsls.

              IF sy-subrc = 0.

                SORT it_outlet BY  lv_outlet.



        *–  fill table “MONITOR” with values of structure “MONITOR_REC”

        *-   to make monitor entries

            … “to cancel the update process

        *    raise exception type CX_RSROUT_ABORT.

            LOOP AT RESULT_PACKAGE ASSIGNING <result_fields>.

              CLEAR wa_stat2.

              IF v_salesman = <result_fields>-/bic/zemplye

                AND v_month = <result_fields>-calmonth.



                CLEAR v_salesman . CLEAR v_month.

                v_salesman = <result_fields>-/bic/zemplye.

                v_month = <result_fields>-calmonth.

                LOOP AT it_stat2 INTO wa_stat2

                  WHERE /bic/zemplye = <result_fields>-/bic/zemplye

                  AND /bic/zcustsls NE <result_fields>-/bic/zcustsls.

        *          st_month =  wa_stat2-/bic/zsdate+0(6).

        *          en_month = wa_stat2-/bic/zedate+0(6).

        *          IF v_month GE st_month and v_month LE en_month .

                  <result_fields>-/bic/zcustsls = wa_stat2-/bic/zcustsls.

                  CLEAR : wa_outlet.

                  READ TABLE it_outlet INTO wa_outlet

                      WITH KEY lv_outlet = wa_stat2-/bic/zcustsls

                      BINARY SEARCH.

                  IF sy-subrc = 0.

                    <result_fields>-/bic/zouttyp = wa_outlet-lv_outtype.

                    if wa_outlet-lv_Outsubtype is not INITIAL.

                    <result_fields>-/BIC/ZOUTGRP = wa_outlet-lv_Outsubtype.


                    IF wa_stat2-/bic/zotlkvgr1 NE 2 .

                      <result_fields>-/bic/zspjpstat = ‘N’.

                      <result_fields>-/bic/zicustsls =  wa_stat2-/bic/zcustsls.

                      “<RESULT_FIELDS>-/BIC/ZMATERIAL = ‘ ‘.

                      <result_fields>-/bic/znetsle = ‘ ‘.

                      <result_fields>-/bic/zacustsls = ‘ ‘.

                      APPEND <result_fields> TO result1.

                    ELSEIF wa_stat2-/bic/zotlkvgr1 = 2 .

                      <result_fields>-/bic/zspjpstat = ‘Y’.

                      <result_fields>-/bic/zacustsls =  wa_stat2-/bic/zcustsls.

        “<result_fields>-/BIC/ZOUTGRP = wa_stat2-/BIC/ZOUTGRP.

                      “<RESULT_FIELDS>-/BIC/ZMATERIAL = ‘ ‘.

                      <result_fields>-/bic/znetsle = ‘ ‘.

                      <result_fields>-/bic/zicustsls = ‘ ‘.

                      APPEND <result_fields> TO result1.






            UNASSIGN: <result_fields>.

            LOOP AT result1 ASSIGNING <result_fields>.

              IF <result_fields>-/bic/znetsle LT 0.

                <result_fields>-flag = ‘1’.


                <result_fields>-flag = ‘0’.



            SORT result1 BY /bic/zemplye /bic/zrouteid /bic/zouttyp

                            /bic/zoutgrp /bic/zcustsls distr_chan salesorg

                            division calmonth flag




            DELETE ADJACENT DUPLICATES FROM result1 COMPARING /bic/zemplye

                        /bic/zrouteid /bic/zouttyp /bic/zoutgrp /bic/zcustsls

                        distr_chan salesorg division calmonth.



            RESULT_PACKAGE[] = result1[].

            LOOP AT RESULT_PACKAGE ASSIGNING <result_fields>.

              v_count = v_count + 1.

              <result_fields>-record = v_count.

              CLEAR wa_stat.

              READ TABLE it_stat INTO wa_stat

                WITH KEY /bic/zemplye = <result_fields>-/bic/zemplye

                      /bic/zcustsls = <result_fields>-/bic/zcustsls.

              IF sy-subrc = 0.

                IF wa_stat-/bic/zotlkvgr1 NE 2.

                  <result_fields>-/bic/zspjpstat = ‘N’.

                  <result_fields>-/bic/zicustsls = <result_fields>-/bic/zcustsls


                ELSEIF wa_stat-/bic/zotlkvgr1 = 2.

                  <result_fields>-/bic/zspjpstat = ‘Y’.

                  <result_fields>-/bic/zacustsls = <result_fields>-/bic/zcustsls




              IF <result_fields>-/bic/zacustsls IS INITIAL

                AND <result_fields>-/bic/zicustsls IS INITIAL .

                <result_fields>-/bic/zicustsls = <result_fields>-/bic/zcustsls.



        *$*$ end of routine – insert your code only before this line         *-*

          ENDMETHOD.                    “end_routine