You are on page 1of 10

Performance: Use of Field Symbol Vs Work Area To use the Field-symbols against the Work Area for Internal

table processing. Well also measure the difference between both of the techniques.

Basics
Internal table processing is essential part of any ABAP program. Generally, we use the explicit work area to process the internal table like appending & modifying records. We can reduce the time and improve the performance of the program by using the field-symbols. When we use the LOOP construct with the explicit work area, system need to engage the resources to put the required record in the work area, process it and move it back to the table if the needed. This additional processing time could be saved by using the field-symbol. By using the fieldsymbols we can save this additional time and improve the performance. Field-symbols are similar to dereferenced pointers in C. While using the field-symbol, system uses the same memory allocated to that particular field in the record instead of moving it to work area and processing. More on field-symbols can be found at: Field-Symbols on SAP Help. This code snippet shows how to use the field-symbols to process the loop with time measurement.

Demo to measure performance


Check out this demo application to measure the performance while using Field-Symbols and work area.
*&---------------------------------------------------------------------* *& Illustrate the performance gain by using the field-symbols *& over header areas *&---------------------------------------------------------------------* REPORT ZSK21.

DATA: I_BSEG TYPE STANDARD TABLE OF BSEG, WA_BSEG LIKE LINE OF I_BSEG. DATA: LV_FLAG TYPE FLAG, LV_STA_TIME TYPE TIMESTAMPL, LV_END_TIME TYPE TIMESTAMPL, LV_DIFF_W TYPE P DECIMALS 5, LV_DIFF_F LIKE LV_DIFF_W, LV_SAVE LIKE LV_DIFF_W. FIELD-SYMBOLS: <FS_BSEG> LIKE LINE OF I_BSEG. * data selection = 10,000 records SELECT * FROM BSEG INTO TABLE I_BSEG UP TO 10 ROWS. * Begin - Processing with Work area GET TIME STAMP FIELD LV_STA_TIME. LOOP AT I_BSEG INTO WA_BSEG. IF LV_FLAG = 'X'. WA_BSEG-SGTXT = 'TEST'. MODIFY I_BSEG FROM WA_BSEG.

ENDIF. CLEAR WA_BSEG. IF LV_FLAG IS INITIAL. LV_FLAG = 'X'. ENDIF. ENDLOOP. GET TIME STAMP FIELD LV_END_TIME. LV_DIFF_W = LV_END_TIME - LV_STA_TIME. WRITE: /(15) 'Work area', LV_DIFF_W. * End - Processing with Work Area * CLEAR: LV_FLAG, LV_STA_TIME, LV_END_TIME. * Begin - Processing with Field-Symbols GET TIME STAMP FIELD LV_STA_TIME. LOOP AT I_BSEG ASSIGNING <FS_BSEG>. IF LV_FLAG = 'X'. <FS_BSEG>-SGTXT = 'TEST'. ENDIF. IF LV_FLAG IS INITIAL. LV_FLAG = 'X'. ENDIF. ENDLOOP. GET TIME STAMP FIELD LV_END_TIME. LV_DIFF_F = LV_END_TIME - LV_STA_TIME. WRITE: /(15) 'Field-Symbol', LV_DIFF_F. * End - Processing with Work Area * * Net time saving LV_SAVE = LV_DIFF_W - LV_DIFF_F. WRITE: /(15) 'Total Save', LV_SAVE. WRITE: / 'Done'.

Some statistics:
In this performance measurement, time taken by the work area to process is considered as the 100%. By using the field-symbols, we can definitely improve the performance.

Parallel Cursor To speed up performance of Nested LOOP


Technique to speed up the performance of the Nested LOOP Parallel Cursor Im back after a long break. Today, we will tackle down the biggest performance related issue around the Nested Loops. Traditionally in ABAP, we use the LOOP using the WHERE clause for Nested loops. This type of nested loops is very common in our day-to-day programming. But, the cost, in terms of performance, is higher when we use the nested loops. This cost would become a key issue when working with huge tables e.g. BKPF & BSEG, VBAK & VBAP, MKPF & MSEG. Sometimes, this cost increases and reaches to the point where program fails to finish the execution. We have the concept of Parallel Cursor exists in ABAP to overcome this hurdle and reduce this cost. In parallel cursor, we first try to see if there is any entry exist in the second table inside the LOOP construct of first table. We use the READ .. WITH KEY .. BINARY SEARCH to check if the entry exist in the second table. We use this record number SY-TABIX to LOOP on the second table using LOOP .. FROM index. This code snippet gives us the idea of the time taken by both the nested loops and the parallel cursor loops.
*&---------------------------------------------------------------------* *& Report ZTEST_NP_PARALLEL_CURSOR *& Purpose: Illustration on how to use Parallel Cursor *&---------------------------------------------------------------------* * REPORT ztest_np_parallel_cursor. * TYPES: ty_t_vbak TYPE STANDARD TABLE OF vbak. DATA: it_vbak TYPE ty_t_vbak . * TYPES: ty_t_vbap TYPE STANDARD TABLE OF vbap. DATA: it_vbap TYPE ty_t_vbap. * FIELD-SYMBOLS: <lfs_vbak> LIKE LINE OF it_vbak, <lfs_vbap> LIKE LINE OF it_vbap. * * necessary data selection SELECT * FROM vbak INTO TABLE it_vbak UP TO 1000 ROWS. CHECK it_vbak IS NOT INITIAL. SELECT * FROM vbap INTO TABLE it_vbap FOR ALL ENTRIES IN it_vbak WHERE vbeln = it_vbak-vbeln. * DATA: lv_start_time TYPE timestampl, lv_end_time TYPE timestampl, lv_diff TYPE timestampl. DATA: lv_tabix TYPE i.

* *...... Normal Nested Loop ................................. * Get the Start Time GET TIME STAMP FIELD lv_start_time. * * Nested Loop LOOP AT it_vbak ASSIGNING <lfs_vbak>. LOOP AT it_vbap ASSIGNING <lfs_vbap> WHERE vbeln = <lfs_vbak>-vbeln. ENDLOOP. ENDLOOP. * * Get the end time GET TIME STAMP FIELD lv_end_time. * * Actual time Spent: lv_diff = lv_end_time - lv_start_time. WRITE: /(50) 'Time Spent on Nested Loop', lv_diff. * CLEAR: lv_start_time, lv_end_time, lv_diff. * *....... Parallel Cursor with Nested Loop ....................... * Get the Start Time GET TIME STAMP FIELD lv_start_time. * * Starting the Parallel Cursor SORT: it_vbak BY vbeln, it_vbap BY vbeln. LOOP AT it_vbak ASSIGNING <lfs_vbak>. * * Read the second internal table with BINARY SEARCH READ TABLE it_vbap TRANSPORTING NO FIELDS WITH KEY vbeln = <lfs_vbak>-vbeln BINARY SEARCH. * Get the TABIX number lv_tabix = sy-tabix. * Start the LOOP from the first accessed record in * previous READ i.e. LV_TABIX LOOP AT it_vbap FROM lv_tabix ASSIGNING <lfs_vbap> . * * End the LOOP, when there is no more record with similar key IF <lfs_vbap>-vbeln <> <lfs_vbak>-vbeln. EXIT. ENDIF. * Rest of the logic would go from here... * ENDLOOP. * ENDLOOP. * * Get the end time GET TIME STAMP FIELD lv_end_time. * * Actual time Spent: lv_diff = lv_end_time - lv_start_time. WRITE: /(50) 'Time Specnt on Parallel Cursor Nested loops:', lv_diff.

I ran this program multiple times and capture this statistics.

Parallel Cursor-2 Without using Read Table


In previous post Parallel Cursor To speed up performance of Nested LOOP, we have seen a technique how to speed up the performance of the nested LOOP constructs in ABAP. In todays post, we will see another variance of the Parallel cursor technique. In this technique, we will exit out the inner LOOP when both keys are not matching by saving the LOOP index in a variable. This index variable would be used in the LOOP construct to start the LOOP. Initially, this index variable would be set to 1. Statistics shows that this new technique is powerful over the technique as shown in the previous post which uses the READ TABLE. Here is the code snippet to achieve this Parallel Cursor technique:
*&---------------------------------------------------------------------* *& Report ZTEST_NP_PARALLEL_CURSOR *& Purpose: Illustration on how to use Parallel Cursor *&---------------------------------------------------------------------* * REPORT ztest_np_parallel_cursor. * TYPES: ty_t_vbak TYPE STANDARD TABLE OF vbak. DATA: it_vbak TYPE ty_t_vbak . * TYPES: ty_t_vbap TYPE STANDARD TABLE OF vbap. DATA: it_vbap TYPE ty_t_vbap. * FIELD-SYMBOLS: <lfs_vbak> LIKE LINE OF it_vbak, <lfs_vbap> LIKE LINE OF it_vbap. * * necessary data selection SELECT * FROM vbak INTO TABLE it_vbak UP TO 100 ROWS. CHECK it_vbak IS NOT INITIAL. SELECT * FROM vbap INTO TABLE it_vbap FOR ALL ENTRIES IN it_vbak WHERE vbeln = it_vbak-vbeln. * DATA: lv_start_time TYPE timestampl, lv_end_time TYPE timestampl, lv_diff TYPE timestampl. DATA: lv_tabix TYPE i. * *....... Parallel Cursor with Nested Loop .......................

* Get the Start Time GET TIME STAMP FIELD lv_start_time. * * Starting the Parallel Cursor SORT: it_vbak BY vbeln, it_vbap BY vbeln. LOOP AT it_vbak ASSIGNING <lfs_vbak>. * * Read the second internal table with BINARY SEARCH READ TABLE it_vbap TRANSPORTING NO FIELDS WITH KEY vbeln = <lfs_vbak>-vbeln BINARY SEARCH. * Get the TABIX number lv_tabix = sy-tabix. * Start the LOOP from the first accessed record in * previous READ i.e. LV_TABIX LOOP AT it_vbap FROM lv_tabix ASSIGNING <lfs_vbap> . * * End the LOOP, when there is no more record with similar key IF <lfs_vbap>-vbeln <> <lfs_vbak>-vbeln. EXIT. ENDIF. * Rest of the logic would go from here... * ENDLOOP. * ENDLOOP. * * Get the end time GET TIME STAMP FIELD lv_end_time. * * Actual time Spent: lv_diff = lv_end_time - lv_start_time. WRITE: /(50) 'Time Spent on Parallel Cursor Nested loops:', lv_diff. CLEAR: lv_start_time, lv_end_time, lv_diff. * *....... Parallel Cursor - 2 with Nested Loop ................... CLEAR lv_tabix. * Get the Start Time GET TIME STAMP FIELD lv_start_time. * * Starting the Parallel Cursor SORT: it_vbak BY vbeln, it_vbap BY vbeln. lv_tabix = 1. " Set the starting index 1 LOOP AT it_vbak ASSIGNING <lfs_vbak>. * * Start the nested LOOP from the index LOOP AT it_vbap FROM lv_tabix ASSIGNING <lfs_vbap>. * Save index & Exit the loop, if the keys are not same IF <lfs_vbak>-vbeln <> <lfs_vbap>-vbeln. lv_tabix = sy-tabix. EXIT. ENDIF. * Rest of the logic would go from here... * ENDLOOP.

ENDLOOP. * * Get the end time GET TIME STAMP FIELD lv_end_time. * * Actual time Spent: lv_diff = lv_end_time - lv_start_time. WRITE: /(50) 'Time Spent on Parallel Cursor 2 Nested loops', lv_diff. CLEAR: lv_start_time, lv_end_time, lv_diff.

This statistics and graph shows the time used by the nested LOOP as the 100%. For the 1000 VBAK records, parallel cursor technique with READ consumes 1.84% time compare to nested LOOPs 100%. This technique without READ TABLE only requires 1.05% time compare to 100% of nested LOOPs.

Your program gives me a lot inspiration. I also have some problem when I use this code. so I made some improvement. Hope it help for anybody. LOOP AT it_vbak ASSIGNING lfs_vbak. LOOP AT it_vbap FROM lv_tabix ASSIGNING lfs_vbap. IF lfs_vbak-vbeln < lfs_vbap-vbeln. lv_tabix = sy-tabix. EXIT. ELSEIF lfs_vbak-vbeln = lfs_vbap-vbeln. * Rest of the logic would go from here ELSE. * nothing here ENDIF. ENDLOOP. ENDLOOP.

SAP has many build in functions that displays Pop-Up Dialog Screens. Pop up a dialog screen and allow user to pick a selection WS_MSG - Create a dialog box in which you display an one-line message. POPUP_TO_CONFIRM_STEP - Create a dialog box in which you make a question whether the user wishes to perform the step. POPUP_TO_CONFIRM_WITH_MESSAGE - Create a dialog box in which you inform the user about a specific decision point during an action. POPUP_TO_CONFIRM_WITH_VALUE - Create a dialog box in which you make a question whether the user wishes to perform a processing step with a particular object. POPUP_TO_DECIDE - Provide user with several choices as radio buttons POPUP_TO_DECIDE_WITH_MESSAGE - Create a dialog box in which you inform the user about a specific decision point via a diagnosis text. POPUP_TO_DISPLAY_TEXT - Create a dialog box in which you display a two-line message. POPUP_TO_SELECT_MONTH - Popup to choose a month POPUP_WITH_TABLE_DISPLAY - Provide a display of a table for user to select one, with the value of the table line returned when selected. POPUP_TO_CONFIRM - Pop-up dialog confirm an action before it is carried out. POPUP_TO_DISPLAY_TEXT - Displays a text in a modal screen POPUP_TO_INFORM - Displays several lines of text. No OK or Cancel buttons. POPUP_TO_CONFIRM/POPUP_TO_DISPLAY_TEXT. TH_POPUP - Display a popup system message on a specific users screen. POPUP_TO_CONFIRM_LOSS_OF_DATA - Create a dialog box in which you make a question whether the user wishes to perform a processing step with loss of data. POPUP_TO_CONFIRM_STEP - Create a dialog box in which you make a question whether the user wishes to perform the step.

POPUP_TO_CONFIRM_WITH_MESSAGE - Create a dialog box in which you inform the user about a specific decision point during an action. POPUP_TO_CONFIRM_WITH_VALUE - Create a dialog box in which you make a question whether the user wishes to perform a processing step with a particular object. POPUP_TO_DECIDE - Provide user with several choices as radio buttons POPUP_TO_DECIDE_WITH_MESSAGE - Create a dialog box in which you inform the user about a specific decision point via a diagnosis text. POPUP_TO_DISPLAY_TEXT - Create a dialog box in which you display a two-line message. POPUP_WITH_TABLE_DISPLAY - Provide a display of a table for user to select one, with the value of the table line returned when selected. POPUP_TO_CONFIRM_LOSS_OF_DATA - Create a dialog box in which you make a question whether the user wishes to perform a processing step with loss of data. POPUP_TO_CONFIRM_STEP - Create a dialog box in which you make a question whether the user wishes to perform the step. POPUP_TO_CONFIRM_WITH_MESSAGE - Create a dialog box in which you inform the user about a specific decision point during an action. POPUP_TO_CONFIRM_WITH_VALUE - Create a dialog box in which you make a question whether the user wishes to perform a processing step with a particular object. POPUP_TO_DECIDE - Provide user with several choices as radio buttons POPUP_TO_DECIDE_WITH_MESSAGE - Create a dialog box in which you inform the user about a specific decision point via a diagnosis text. POPUP_TO_DISPLAY_TEXT - Create a dialog box in which you display a two-line message. POPUP_WITH_TABLE_DISPLAY - Provide a display of a table for user to select one, with the value of the table line returned when selected.

Below are an example of the use of POPUP_TO_CONFIRM:

Report zsk. DATA RETURNCODE(1) TYPE C. CALL FUNCTION 'POPUP_TO_CONFIRM' EXPORTING TITLEBAR = 'Delete selected lines' TEXT_QUESTION = 'Are you sure you want to delete ?' TEXT_BUTTON_1 = 'OK' ICON_BUTTON_1 = 'ICON_OKAY' TEXT_BUTTON_2 = 'Cancel' ICON_BUTTON_2 = 'ICON_CANCEL' DEFAULT_BUTTON = '2' DISPLAY_CANCEL_BUTTON = '' IMPORTING ANSWER = RETURNCODE. * Test the returnkode. If the first button is pushed the returncode is 1 and if the second * button is pushed the returncode is 2 IF RETURNCODE = 1. PERFORM DELETE. ENDIF. *&---------------------------------------------------------------------* *& Form DELETE *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* FORM DELETE . leave to screen 0. ENDFORM. " DELETE

You might also like