无常笔记ABAP Cheat Sheets中文导读全站搜索

英文原文:SAP-samples · 上游版本 d43eb13c4c7c · 原始 Markdown

ABAP Performance Notes

Various factors can influence the runtime of an ABAP program. Key elements affecting performance include the efficiency of database interactions and the processing of internal tables. This cheat sheet explores a selection of performance-related examples. These examples aim to illustrate potentially inefficient techniques and use of statements.

[!NOTE]

⬆️ back to top

Database Access

Reducing the Result Set

[!NOTE] Complex conditions in the WHERE and HAVING clauses can impact performance. Statements that check for equality (=/EQ) and use AND are particularly efficient. Other operators like NOT and OR require more effort from the database to search for data sets.

⬆️ back to top

Reducing the Data Volume

Minimizing the transferred data volume can be achieved by considering the following aspects:

[!NOTE] Using aggregate functions, such as SUM, AVG or COUNT, for calculations can effectively reduce the data volume transferred from the database instead of performing calculations in the program. These aggregate functions incur runtime costs on the database. Positive performance impact can depend on factors such as the efficiency of function use and the number of data sets processed.

⬆️ back to top

Reducing Database Accesses

You can minimize database accesses by considering the following aspects:

⬆️ back to top

Using CDS views

⬆️ back to top

Dynamic and Static ABAP SQL Statements

⬆️ back to top

Using Buffering

⬆️ back to top

Using Indexes

⬆️ back to top

Processing Internal Tables

[!NOTE]

⬆️ back to top

Single Line Access Using the Primary Table Key and Free Keys

⬆️ back to top

Multiline Access and Applying a WHERE Condition

⬆️ back to top

Reducing Content Transfer

Contexts of reducing content transfer are, for example, the following:

⬆️ back to top

Block-wise Processing of Table Lines

⬆️ back to top

Using Secondary Table Keys to Improve Read Performance

[!NOTE] ABAP statements implicitly use the primary table key, while secondary table keys must be explicitly specified.

⬆️ back to top

Applying a Sort Key when Sorting Internal Tables

⬆️ back to top

Clearing with CLEAR and FREE

⬆️ back to top

Dynamic and Static Specifications when Processing Internal Tables

⬆️ back to top

Overusing Table Expressions

🟢 Click to expand for example code

The following example demonstrates multiple reads and writes using table expressions. The first loop includes multiple table expressions, while the second loop is designed differently, referencing the table line by a field symbol and involving fewer table expressions. The runtimes of both loops are recorded, showing that the second loop has a significantly shorter runtime than the first.

Note: This example is for exploration, experimentation, and demonstration. It is not intended for accurate runtime or performance testing and is not a suitable method for such purposes.

CLASS zcl_demo_abap DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.


CLASS zcl_demo_abap IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.

CONSTANTS: num_of_repetitions     TYPE i VALUE 100,
           num_of_assignment_runs TYPE i VALUE 1000.

    TYPES: BEGIN OF struct,
             a TYPE i,
             b TYPE i,
             c TYPE i,
             d TYPE i,
             e TYPE i,
             f TYPE i,
           END OF struct.

    DATA it TYPE TABLE OF struct WITH EMPTY KEY.

    it = VALUE #( ( a = 0 b = 0 c = 0 d = 0 e = 0 f = 0 )
                  ( a = 1 b = 1 c = 1 d = 1 e = 1 f = 1 ) ).
    DATA(it_original) = it.

    DATA runtime_tab TYPE TABLE OF decfloat34 WITH EMPTY KEY.

    DO num_of_repetitions TIMES.
      DATA(ts1) = utclong_current( ).
      DO num_of_assignment_runs TIMES.
        it[ 1 ]-a = sy-index.
        it[ 1 ]-b = sy-index.
        it[ 1 ]-c = sy-index.
        it[ 2 ]-d = sy-index.
        it[ 2 ]-e = sy-index.
        it[ 2 ]-f = sy-index.
        it[ 1 ]-d = it[ 2 ]-d.
        it[ 1 ]-e = it[ 2 ]-e.
        it[ 1 ]-f = it[ 2 ]-f.
        INSERT it[ 1 ] INTO TABLE it.
        INSERT it[ 2 ] INTO TABLE it.
      ENDDO.
      DATA(ts2) = utclong_current( ).
      cl_abap_utclong=>diff( EXPORTING high    = ts2
                                       low     = ts1
                             IMPORTING seconds = DATA(seconds) ).

      APPEND seconds TO runtime_tab.
    ENDDO.

    SORT runtime_tab BY table_line ASCENDING.

    out->write( `Multiple table expressions, fastest run:` ).
    out->write( runtime_tab[ 1 ] ).

    CLEAR runtime_tab.
    it = it_original.

    DO num_of_repetitions TIMES.
      ts1 = utclong_current( ).
      DO num_of_assignment_runs TIMES.
        ASSIGN it[ 1 ] TO FIELD-SYMBOL(<fs1>).
        ASSIGN it[ 2 ] TO FIELD-SYMBOL(<fs2>).
        <fs1>-a = sy-index.
        <fs1>-b = sy-index.
        <fs1>-c = sy-index.
        <fs2>-d = sy-index.
        <fs2>-e = sy-index.
        <fs2>-f = sy-index.
        <fs1>-d = <fs2>-d.
        <fs1>-e = <fs2>-e.
        <fs1>-f = <fs2>-f.
        INSERT <fs1> INTO TABLE it.
        INSERT <fs2> INTO TABLE it.
      ENDDO.
      ts2 = utclong_current( ).
      cl_abap_utclong=>diff( EXPORTING high    = ts2
                                       low     = ts1
                             IMPORTING seconds = seconds ).

      APPEND seconds TO runtime_tab.
    ENDDO.

    SORT runtime_tab BY table_line ASCENDING.

    out->write( `Avoiding overusing table expressions, fastest run:` ).
    out->write( runtime_tab[ 1 ] ).
  ENDMETHOD.
ENDCLASS.

⬆️ back to top

Miscellaneous Contexts

Using DO and WHILE

A WHILE loop may be faster than a DO loop (including an explicit EXIT).

⬆️ back to top

Using Strings

Examples of string-related contexts:

⬆️ back to top

Avoiding Implicit Type Conversions

⬆️ back to top

Passing by Reference and Value

⬆️ back to top

Parallel Processing

⬆️ back to top

Executable Example

To try the example out, create a demo class named zcl_demo_abap in the SAP Business AI Platform, ABAP environment and paste the code into it. The example also includes a local class in the CCIMP include (Local Types tab in ADT). After activation, choose F9 in ADT to execute the class. The example is set up to display output in the console. The class execution may take a while to complete.

The simplified example is set up as follows:

Overview of covered examples (see also the inline comments in the method implementations):

[!NOTE]

🟢 Click to expand for example code
Class include Code

Global class

"! <p class="shorttext"><strong>Performance Notes</strong><br/>ABAP cheat sheet example class</p>
"!
"! <p>The example class includes several methods that explore both inefficient and potentially more
"! efficient code examples affecting performance.</p>
"! <p>In ADT, choose F9 in ADT to run the class.</p>
"!
"! <h2>Note</h2>
"! <ul><li>As a prerequisite, you have imported the ABAP cheat sheet repository since the
"! example uses some of its artifacts.</li>
"! <li>The example is for exploration, experimentation, and demonstration. It is not intended for accurate
"! runtime or performance testing and is not a suitable method for such purposes. Due to its simplified nature,
"! results may vary and not be entirely accurate, even across multiple runs.</li>
"! <li>Note the disclaimer in the ABAP cheat sheet repository.</li></ul>
CLASS zcl_demo_abap DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.
    CLASS-METHODS class_constructor.

  PROTECTED SECTION.
  PRIVATE SECTION.

    "Constants used for DO n TIMES statements
    CONSTANTS loop_count_5 TYPE i VALUE 5.
    CONSTANTS loop_count_10 TYPE i VALUE 10.
    CONSTANTS loop_count_50 TYPE i VALUE 50.
    CONSTANTS loop_count_250 TYPE i VALUE 250.
    CONSTANTS loop_count_500 TYPE i VALUE 500.
    CONSTANTS loop_count_1000 TYPE i VALUE 1000.

    "Components used for calculating the average runtime
    DATA: ts1         TYPE utclong,
          runtime_tab TYPE TABLE OF decfloat34 WITH EMPTY KEY,
          runtime     TYPE decfloat34.

    "Collects timestamps to calculate the average runtime
    METHODS store_runtime IMPORTING high TYPE utclong
                                    low  TYPE utclong.

    "Calculates the average runtime
    METHODS get_avg_runtime RETURNING VALUE(avg_runtime) TYPE decfloat34.

    "Exemplary methods containing (in)efficient demo implementations
    METHODS:
      sql_01_reduce_t_rows_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_01_reduce_t_rows_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_02_reduce_t_rows_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_02_reduce_t_rows_b IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_02_reduce_t_rows_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_03_reduce_t_rows_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_03_reduce_t_rows_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_04_reduce_data_volume_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_04_reduce_data_volume_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_05_reduce_db_access_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_05_reduce_db_access_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_06_reduce_db_access_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_06_reduce_db_access_b IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_06_reduce_db_access_c IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_06_reduce_db_access_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_07_reduce_db_access_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_07_reduce_db_access_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_08_reduce_db_access_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_08_reduce_db_access_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_09_update_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_09_update_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_10_db_logic_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_10_db_logic_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_11_dynamic_sql_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      sql_11_dynamic_sql_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_01_table_key_read_a_std IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_01_table_key_read_b_so IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_01_table_key_read_z_ha IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_02_incomplete_t_key_a_so IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_02_incomplete_t_key_b_ha IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_02_incomplete_t_key_z_so IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_03_std_binary_search_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_03_std_binary_search_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_04_loop_a_std IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_04_loop_b_so_compl_key IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_04_loop_c_so_incompl_key IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_04_loop_d_so_incompl_k_la IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_04_loop_e_ha_compl_key IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_04_loop_z_ha_incompl_key IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_05_loop_no_where_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_05_loop_no_where_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_06_loop_target_a_wa IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_06_loop_target_b_fs IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_06_loop_target_z_dref IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_07_loop_modify_a_wa IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_07_loop_modify_b_fs IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_07_loop_modify_z_dref IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_08_block_insert_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_08_block_insert_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_09_restrict_copy_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_09_restrict_copy_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_10_sec_key_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_10_sec_key_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_11_sec_key_freq_mod_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_11_sec_key_freq_mod_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_12_sort_itab_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_12_sort_itab_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_13_clear_free_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_13_clear_free_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_14_dyn_itab_spec_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_14_dyn_itab_spec_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_15_read_where_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_15_read_where_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_16_find_replace_table_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      itab_16_find_replace_table_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      misc_01_while_do_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      misc_01_while_do_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      misc_02_strings_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      misc_02_strings_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      misc_03_string_templates_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      misc_03_string_templates_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      misc_04_search_pattern_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      misc_04_search_pattern_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      misc_05_type_conversion_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      misc_05_type_conversion_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      misc_06_formal_parameters_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      misc_06_formal_parameters_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      misc_07_parallel_processing_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      misc_07_parallel_processing_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      eml_01_eml_in_loop_a IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname,
      eml_01_eml_in_loop_z IMPORTING out TYPE REF TO if_oo_adt_classrun_out name TYPE abap_methname.

    "Methods demonstrating parameter passing by value and reference
    METHODS: meth_pass_by_ref IMPORTING a TYPE i
                                        b TYPE i
                                        c TYPE string_table
                                        d TYPE string_table
                              EXPORTING e TYPE i
                                        f TYPE i
                                        g TYPE string_table
                                        h TYPE string_table,
      meth_pass_by_value IMPORTING VALUE(i) TYPE i
                                   VALUE(j) TYPE i
                                   VALUE(k) TYPE string_table
                                   VALUE(l) TYPE string_table
                         EXPORTING VALUE(m) TYPE i
                                   VALUE(n) TYPE i
                                   VALUE(o) TYPE string_table
                                   VALUE(p) TYPE string_table.

    "Demo internal tables used by the examples
    TYPES: BEGIN OF ty_tab,
             comp1 TYPE i,
             comp2 TYPE i,
             comp3 TYPE i,
             comp4 TYPE c LENGTH 50,
             comp5 TYPE c LENGTH 50,
             comp6 TYPE i,
           END OF ty_tab.

    CLASS-DATA: standard_tab               TYPE TABLE OF ty_tab WITH NON-UNIQUE KEY comp1,
                sorted_tab                 TYPE SORTED TABLE OF ty_tab WITH UNIQUE KEY comp1,
                hashed_tab                 TYPE HASHED TABLE OF ty_tab WITH UNIQUE KEY comp1,
                standard_tab_w_sec_key     TYPE TABLE OF ty_tab WITH EMPTY KEY WITH NON-UNIQUE SORTED KEY sec_key COMPONENTS comp1,
                sorted_tab_mult_key_comp   TYPE SORTED TABLE OF ty_tab WITH UNIQUE KEY comp1 comp2 comp3,
                hashed_tab_mult_key_comp   TYPE HASHED TABLE OF ty_tab WITH UNIQUE KEY comp1 comp2 comp3,
                standard_tab_w_default_key TYPE TABLE OF ty_tab,
                key_tab                    TYPE TABLE OF zdemo_abap_tab1-key_field WITH EMPTY KEY,
                itab1                      TYPE TABLE OF zdemo_abap_tab1 WITH EMPTY KEY,
                flsch_tab                  TYPE TABLE OF zdemo_abap_flsch WITH EMPTY KEY,
                carr_tab                   TYPE TABLE OF zdemo_abap_carr WITH EMPTY KEY.

    TYPES: BEGIN OF ty_deep_tab,
             comp1 TYPE i,
             comp2 TYPE i,
             comp3 TYPE i,
             comp4 TYPE c LENGTH 50,
             comp5 TYPE c LENGTH 50,
             comp6 TYPE i,
             comp7 TYPE string_table,
             comp8 TYPE ty_tab,
           END OF ty_deep_tab.

    CLASS-DATA deep_standard_tab TYPE TABLE OF ty_deep_tab WITH EMPTY KEY.

ENDCLASS.


CLASS zcl_demo_abap IMPLEMENTATION.

  METHOD if_oo_adt_classrun~main.

    "Dynamically calling all exemplary methods (excluding the main method)
    "The method names are retrieved using RTTI. Refer to the Dynamic Programming ABAP cheat sheet.
    DATA(oref) = NEW zcl_demo_abap( ).
    DATA(methods) = CAST cl_abap_classdescr( cl_abap_typedescr=>describe_by_object_ref( me ) )->methods.
    DELETE methods WHERE name = 'IF_OO_ADT_CLASSRUN~MAIN'.
    SORT methods BY name ASCENDING.

    LOOP AT methods INTO DATA(meth_wa).
      TRY.
          CALL METHOD oref->(meth_wa-name) EXPORTING out = out name = meth_wa-name.
        CATCH cx_root.
      ENDTRY.

      "For better readability of the output and reference in the console, inserting a divider
      "after the final method of an example context. These methods include _Z in the name.
      FIND `_Z` IN meth_wa-name IGNORING CASE.
      IF sy-subrc = 0.
        out->write( repeat( val = `*` occ = 70 ) ).
      ENDIF.
    ENDLOOP.
  ENDMETHOD.

  METHOD store_runtime.
    cl_abap_utclong=>diff( EXPORTING high    = high
                                     low     = low
                           IMPORTING seconds = DATA(seconds) ).

    APPEND seconds TO runtime_tab.
  ENDMETHOD.

  METHOD class_constructor.
    "On class execution, multiple tasks are performed preparing the demo.

    "Clearing and populating demo database tables
    zcl_demo_abap_aux=>fill_dbtabs( ).
    DELETE FROM zdemo_abap_tabca.

    DATA rap_tab TYPE TABLE OF zdemo_abap_tab1 WITH EMPTY KEY.

    DO 10 TIMES.
      APPEND VALUE #( key_field = sy-index num1 = sy-index num2 = sy-index ) TO rap_tab.
    ENDDO.

    DELETE FROM zdemo_abap_rapt1.
    INSERT zdemo_abap_rapt1 FROM TABLE @rap_tab.

    DATA demo_tab TYPE TABLE OF zdemo_abap_tab1 WITH EMPTY KEY.

    DO 1000 TIMES.
      APPEND VALUE #( key_field = sy-index char1 = sy-index char2 = sy-index num1 = sy-index num2 = sy-index ) TO demo_tab.
    ENDDO.

    DELETE FROM zdemo_abap_tab1.
    INSERT zdemo_abap_tab1 FROM TABLE @demo_tab.

    "Populating demo internal tables
    DO loop_count_250 TIMES.
      APPEND sy-index TO key_tab.
    ENDDO.

    carr_tab = VALUE #( ( carrid = 'AB' carrname = 'AB Airways' )
          ( carrid = 'CD' carrname = 'CD Airways' )
          ( carrid = 'EF' carrname = 'EF Airways' )
          ( carrid = 'GH' carrname = 'GH Airways' )
          ( carrid = 'IJ' carrname = 'IJ Airways' ) ).

    DO loop_count_1000 TIMES.
      INSERT VALUE #( comp1 = sy-index comp2 = sy-index comp3 = sy-index comp4 = sy-index comp5 = sy-index comp6 = sy-index ) INTO TABLE sorted_tab ASSIGNING FIELD-SYMBOL(<fs>).

      INSERT CORRESPONDING #( <fs> ) INTO TABLE deep_standard_tab ASSIGNING FIELD-SYMBOL(<deep>).
      <deep>-comp7 = VALUE #( ( `A` ) ( `B` ) ( `A` ) ( `P` ) ).
      <deep>-comp8 = <fs>.
    ENDDO.

    INSERT LINES OF sorted_tab INTO TABLE standard_tab.
    INSERT LINES OF sorted_tab INTO TABLE hashed_tab.
    INSERT LINES OF sorted_tab INTO TABLE standard_tab_w_sec_key.
    INSERT LINES OF sorted_tab INTO TABLE sorted_tab_mult_key_comp.
    INSERT LINES OF sorted_tab INTO TABLE hashed_tab_mult_key_comp.
    INSERT LINES OF sorted_tab INTO TABLE standard_tab_w_default_key.
  ENDMETHOD.

  METHOD sql_10_db_logic_a.
    "Using aggregate functions
    "This simplified example does not necessarily show better performance than the
    "other example. The purpose here is to leave calculation tasks to the database,
    "in contrast to the manual calculation.

    DO loop_count_1000 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT AVG( key_field ) AS avg,
             SUM( key_field ) AS sum,
             MAX( key_field ) AS max,
             MIN( key_field ) AS min,
             COUNT( key_field ) AS count
         FROM zdemo_abap_tab1
         INTO @DATA(result).
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.
    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_10_db_logic_z.
    "Reading all table rows, then further processing the data sets
    "to calculate values.

    DATA: BEGIN OF result,
            avg   TYPE decfloat34,
            sum   TYPE i,
            max   TYPE i,
            min   TYPE i,
            count TYPE i,
          END OF result.

    DO loop_count_1000 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT key_field
       FROM zdemo_abap_tab1
       INTO TABLE @DATA(tab).

      IF tab IS NOT INITIAL.
        LOOP AT tab ASSIGNING FIELD-SYMBOL(<fs>).
          result-count += 1.
          result-sum += <fs>-key_field.
          result-max = COND #( WHEN <fs>-key_field > result-max THEN <fs>-key_field ELSE result-max ).
          result-min = COND #( WHEN sy-tabix = 1 THEN <fs>-key_field
                               WHEN <fs>-key_field < result-min THEN <fs>-key_field
                               ELSE result-min ).
        ENDLOOP.
        result-avg = result-sum / result-count.
      ENDIF.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_11_dynamic_sql_a.
    "Using static specification in ABAP SQL statement

    DO loop_count_1000 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT SINGLE carrid, connid, countryfr, cityfrom
         FROM zdemo_abap_flsch
         WHERE carrid <> 'LH'
         INTO NEW @DATA(dref_fl).
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_11_dynamic_sql_z.
    "Dynamic specification in ABAP SQL statement

    DO loop_count_1000 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT SINGLE ('CARRID, CONNID, COUNTRYFR, CITYFROM')
        FROM ('ZDEMO_ABAP_FLSCH')
        WHERE (`CARRID <> 'LH'`)
        INTO NEW @DATA(dref_fl2).
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_01_reduce_t_rows_a.
    "ABAP SQL statement specifying a WHERE clause

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT key_field, char1, char2, num1, num2
        FROM zdemo_abap_tab1
        WHERE key_field < 500
        INTO TABLE @DATA(it1).
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_01_reduce_t_rows_z.
    "ABAP SQL statement not specifying a WHERE clause
    "Instead, reading all data from the database table, processing
    "the content further in a loop, and filtering out data sets.

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT key_field, char1, char2, num1, num2
        FROM zdemo_abap_tab1
        INTO TABLE @DATA(it2).

      LOOP AT it2 REFERENCE INTO DATA(dref2).
        IF dref2->key_field < 500.
          DELETE it2 INDEX sy-tabix.
        ENDIF.
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_02_reduce_t_rows_a.
    "Using SELECT SINGLE to read a single line

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT SINGLE carrid, connid, cityfrom, countryfr, cityto, countryto
       FROM zdemo_abap_flsch
       WHERE carrid = char`LH` AND connid = char`0400`
       INTO @DATA(line).
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_02_reduce_t_rows_b.
    "Reading all data sets from the database table, and reading
    "an entry using READ TABLE.

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT carrid, connid, cityfrom, countryfr, cityto, countryto
        FROM zdemo_abap_flsch
        INTO TABLE @DATA(it3).

      READ TABLE it3 INTO DATA(line4) WITH KEY carrid = 'LH' connid = '0400'.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_03_reduce_t_rows_a.
    "Reading a specific number of data sets from the database table using
    "the UP TO n ROWS addition

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT key_field, char1, char2, num1, num2
         FROM zdemo_abap_tab1
         INTO TABLE @DATA(it5)
         UP TO 100 ROWS.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_03_reduce_t_rows_z.
    "Reading all database table entries and further process the internal table
    "content

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT key_field, char1, char2, num1, num2
             FROM zdemo_abap_tab1
             INTO TABLE @DATA(it6).

      DELETE it6 FROM 101.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_04_reduce_data_volume_a.
    "Specifying columns so that not all columns are read

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT carrid, connid, cityfrom, countryfr, cityto, countryto
       FROM zdemo_abap_flsch
       INTO TABLE @DATA(it7).
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_04_reduce_data_volume_z.
    "Specifying SELECT * to read all columns

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT *
       FROM zdemo_abap_flsch
       INTO TABLE @DATA(it8).
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_05_reduce_db_access_a.
    "Single database access

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT carrid, connid, cityfrom, countryfr, cityto, countryto
       FROM zdemo_abap_flsch
       INTO TABLE @DATA(it9)
       UP TO 5 ROWS.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_05_reduce_db_access_z.
    "Repeated database access in a loop

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      DO 5 TIMES.
        SELECT SINGLE carrid, connid, cityfrom, countryfr, cityto, countryto
           FROM zdemo_abap_flsch
           INTO @DATA(fl_row).
      ENDDO.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_06_reduce_db_access_a.
    "Using an inner join

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT key_field, char1, char2, num1, num2
          FROM zdemo_abap_tab1
          INNER JOIN @key_tab AS tab
          ON zdemo_abap_tab1~key_field = tab~table_line
          INTO CORRESPONDING FIELDS OF TABLE @itab1.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_06_reduce_db_access_b.
    "Using WHERE EXISTS

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT key_field, char1, char2, num1, num2
        FROM zdemo_abap_tab1
        WHERE EXISTS ( SELECT 'X' FROM @key_tab AS tab WHERE zdemo_abap_tab1~key_field = tab~table_line )
        INTO CORRESPONDING FIELDS OF TABLE @itab1.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.


  METHOD sql_06_reduce_db_access_c.
    "Using the FOR ALL ENTRIES addition

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      IF key_tab IS NOT INITIAL.
        SELECT key_field, char1, char2, num1, num2
         FROM zdemo_abap_tab1
         FOR ALL ENTRIES IN @key_tab
         WHERE key_field = @key_tab-table_line
         INTO CORRESPONDING FIELDS OF TABLE @itab1.
      ENDIF.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_06_reduce_db_access_z.
    "Repeated database access in a loop

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT key_tab INTO DATA(wa).
        SELECT key_field, char1, char2, num1, num2
          FROM zdemo_abap_tab1
          WHERE key_field = @wa
          APPENDING CORRESPONDING FIELDS OF TABLE @itab1.
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_07_reduce_db_access_a.
    "Block-wise modify operation

    DELETE FROM zdemo_abap_carr.

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      MODIFY zdemo_abap_carr FROM TABLE @carr_tab.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_07_reduce_db_access_z.
    "Line by line modify operations

    DELETE FROM zdemo_abap_carr.

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT carr_tab INTO DATA(wa_carr).
        MODIFY zdemo_abap_carr FROM @wa_carr.
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_08_reduce_db_access_a.
    "Join

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT fl~carrid, carr~carrname, fl~connid, fl~cityfrom, fl~cityto
         FROM zdemo_abap_flsch AS fl
            LEFT OUTER JOIN zdemo_abap_carr AS carr
              ON fl~carrid = carr~carrid
         INTO TABLE @DATA(it10).
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).

  ENDMETHOD.

  METHOD sql_08_reduce_db_access_z.
    "Nested SELECT loop

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT carrid, CAST( ' ' AS CHAR( 20 ) ) AS carrname,
       connid, cityfrom, cityto
       FROM zdemo_abap_flsch
       INTO @DATA(wa_fl).
        SELECT SINGLE carrname
               FROM zdemo_abap_carr
               WHERE carrid = @wa_fl-carrid
               INTO (@wa_fl-carrname).
        DATA it11 LIKE TABLE OF wa_fl WITH EMPTY KEY.
        it11 = VALUE #( BASE it11 ( wa_fl ) ).
      ENDSELECT.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_09_update_a.
    "UPDATE ... SET statement

    DO loop_count_10 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      UPDATE zdemo_abap_tab1 SET char1 = 'X' WHERE key_field < 20.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_09_update_z.
    "UPDATE statement using a work area

    DO loop_count_10 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT *
        FROM zdemo_abap_tab1
        WHERE key_field < 20
        INTO @DATA(wa_tab).
        wa_tab-char1 = 'X'.
        UPDATE zdemo_abap_tab1 FROM @wa_tab.
      ENDSELECT.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD sql_02_reduce_t_rows_z.
    "Specifying UP TO 1 ROWS to retrieve a single row

    DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SELECT carrid, connid, cityfrom, countryfr, cityto, countryto
        FROM zdemo_abap_flsch
        WHERE carrid = char`LH` AND connid = char`0400`
        INTO TABLE @DATA(it4)
        UP TO 1 ROWS.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime(  ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_01_table_key_read_z_ha.
    "Reading from a hashed table using the primary table key

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      READ TABLE hashed_tab TRANSPORTING NO FIELDS WITH TABLE KEY comp1 = sy-index.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_01_table_key_read_b_so.
    "Reading from a sorted table using the primary table key

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      READ TABLE sorted_tab TRANSPORTING NO FIELDS WITH TABLE KEY comp1 = sy-index.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_01_table_key_read_a_std.
    "Reading from a standard table using the primary table key

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      READ TABLE standard_tab TRANSPORTING NO FIELDS WITH TABLE KEY comp1 = sy-index.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_02_incomplete_t_key_b_ha.
    "Reading from a hashed table using a free key
    "The primary table key is only partially used.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      READ TABLE hashed_tab_mult_key_comp TRANSPORTING NO FIELDS WITH KEY comp1 = sy-index comp2 = sy-index.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_02_incomplete_t_key_a_so.
    "Reading from a sorted table using a free key
    "The primary table key is only partially used.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      READ TABLE sorted_tab_mult_key_comp TRANSPORTING NO FIELDS WITH KEY comp1 = sy-index comp2 = sy-index.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_02_incomplete_t_key_z_so.
    "Reading from a sorted table using a free key
    "The primary table key is only partially used. The key is not left-aligned.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      READ TABLE sorted_tab_mult_key_comp TRANSPORTING NO FIELDS WITH KEY comp2 = sy-index comp3 = sy-index.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD get_avg_runtime.
    "Calculating the average runtime value

    DATA(sum) = REDUCE decfloat34( INIT s = VALUE #( )
                               FOR wa IN runtime_tab
                               NEXT s += wa ).

    TRY.
        avg_runtime = sum / lines( runtime_tab ).
      CATCH cx_sy_zerodivide.
    ENDTRY.

    CLEAR runtime_tab.
  ENDMETHOD.

  METHOD itab_03_std_binary_search_a.
    "Reading from a standard table using a free key and the BINARY SEARCH addition.
    "A SORT statement is executed beforehand.

    SORT standard_tab BY comp2 ASCENDING.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      READ TABLE standard_tab TRANSPORTING NO FIELDS WITH KEY comp2 = sy-index BINARY SEARCH.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_03_std_binary_search_z.
    "Reading from a standard table using a free key. Here, the BINARY SEARCH addition
    "is not specified. A SORT statement is executed beforehand.

    SORT standard_tab BY comp2 ASCENDING.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      READ TABLE standard_tab TRANSPORTING NO FIELDS WITH KEY comp2 = sy-index.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_04_loop_a_std.
    "A standard table is looped across, specifying a WHERE condition.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT standard_tab REFERENCE INTO DATA(dref) WHERE comp1 = 800 AND comp2 = '800' AND comp3 = '800'.
        ...
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_04_loop_b_so_compl_key.
    "A sorted table is looped across, specifying a WHERE condition.
    "The full key is specified.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT sorted_tab_mult_key_comp REFERENCE INTO DATA(dref) WHERE comp1 = 800 AND comp2 = '800' AND comp3 = '800'.
        ...
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_04_loop_c_so_incompl_key.
    "A sorted table is looped across, specifying a WHERE condition.
    "The key is partially specified, but not left-aligned.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT sorted_tab_mult_key_comp REFERENCE INTO DATA(dref) WHERE comp2 = '800' AND comp3 = '800'.
        ...
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_04_loop_d_so_incompl_k_la.
    "A sorted table is looped across, specifying a WHERE condition.
    "The key is partially specified, left-aligned.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT sorted_tab_mult_key_comp REFERENCE INTO DATA(dref) WHERE comp1 = 800 AND comp2 = '800' .
        ...
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_04_loop_e_ha_compl_key.
    "A hashed table is looped across, specifying a WHERE condition.
    "The key is fully specified.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT hashed_tab_mult_key_comp REFERENCE INTO DATA(dref) WHERE comp1 = 800 AND comp2 = '800' AND comp3 = '800' .
        ...
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_04_loop_z_ha_incompl_key.
    "A hashed table is looped across, specifying a WHERE condition.
    "The key is partially specified.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT hashed_tab_mult_key_comp REFERENCE INTO DATA(dref) WHERE comp1 = 800 AND comp2 = '800'.
        ...
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_05_loop_no_where_a.
    "A standard table is looped across, specifying a WHERE condition.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT standard_tab REFERENCE INTO DATA(dref) WHERE comp1 > 800.
        ...
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_05_loop_no_where_z.
    "A standard table is looped across, not specifying a WHERE condition.
    "Instead, an IF constrol structure is implemented in the loop.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT standard_tab REFERENCE INTO DATA(dref).
        IF dref->comp1 > 800.
          CONTINUE.
        ENDIF.
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_06_loop_target_a_wa.
    "A deep standard table is looped across. The target area is a work area.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT deep_standard_tab INTO DATA(wa) WHERE comp1 < 200.
        ...
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_06_loop_target_b_fs.
    "A deep standard table is looped across. The target area is a field symbol.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT deep_standard_tab ASSIGNING FIELD-SYMBOL(<fs>) WHERE comp1 < 200.
        ...
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_06_loop_target_z_dref.
    "A deep standard table is looped across. The target area is a data reference variable.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT deep_standard_tab REFERENCE INTO DATA(dref) WHERE comp1 < 200.
        ...
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_07_loop_modify_a_wa.
    "A standard table is looped across. The target area is a work area.
    "The read table line is modified using a MODIFY statement based
    "on the work area.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT standard_tab INTO DATA(wa) WHERE comp1 < 800.
        wa-comp6 += 1.
        MODIFY standard_tab FROM wa.
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_07_loop_modify_b_fs.
    "A standard table is looped across. The target area is a field symbol.
    "The read table line is directly modified using the field symbol.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT standard_tab ASSIGNING FIELD-SYMBOL(<fs>) WHERE comp1 < 800.
        <fs>-comp6 += 1.
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_07_loop_modify_z_dref.
    "A standard table is looped across. The target area is a data reference variable.
    "The read table line is directly modified using the data reference variable.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT standard_tab REFERENCE INTO DATA(dref) WHERE comp1 < 800.
        dref->comp6 += 1.
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_08_block_insert_a.
    "Block-wise insertion of table content

    "Preparing demo data
    DATA str_tab_a TYPE string_table.
    DATA str_tab_b TYPE string_table.
    DO 1000 TIMES.
      APPEND sy-tabix TO str_tab_a.
    ENDDO.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      APPEND LINES OF str_tab_a TO str_tab_b.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_08_block_insert_z.
    "Line by line insertion of table content

    "Preparing demo data
    DATA str_tab_a TYPE string_table.
    DATA str_tab_b TYPE string_table.
    DO 1000 TIMES.
      APPEND sy-tabix TO str_tab_a.
    ENDDO.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT str_tab_a INTO DATA(wa).
        APPEND wa TO str_tab_b.
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_09_restrict_copy_a.
    "Restricting the copying of table line content using the TRANSPORTING addition

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT deep_standard_tab INTO DATA(wa) WHERE comp1 < 400.
        wa-comp6 += 1.
        MODIFY deep_standard_tab FROM wa TRANSPORTING comp6.
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_09_restrict_copy_z.
    "Not using the TRANSPORTING addition
    "Instead, all fields except one are overwritten with the same content
    "available in the work area.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT deep_standard_tab INTO DATA(wa) WHERE comp1 < 400.
        wa-comp6 += 1.
        MODIFY deep_standard_tab FROM wa.
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_10_sec_key_a.
    "Reading single lines from a standard table using a secondary table key

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      READ TABLE standard_tab_w_sec_key TRANSPORTING NO FIELDS WITH TABLE KEY sec_key COMPONENTS comp1 = sy-index.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_10_sec_key_z.
    "Reading single lines from a standard table using the primary table key
    "The primary table key of the demo internal table here corresponds to the secondary table
    "key in the itab_10_sec_key_a method.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      READ TABLE standard_tab TRANSPORTING NO FIELDS WITH TABLE KEY comp1 = sy-index.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_11_sec_key_freq_mod_a.
    "A standard table is looped across. The table specifies a secondary table key.
    "Reads are performed in the loop.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT standard_tab_w_sec_key ASSIGNING FIELD-SYMBOL(<fs>) TO 200.
        DATA(comp) = <fs>-comp6.
        READ TABLE standard_tab_w_sec_key TRANSPORTING NO FIELDS WITH TABLE KEY sec_key COMPONENTS comp1 = sy-tabix.
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_11_sec_key_freq_mod_z.
    "A standard table is looped across. The table specifies a secondary table key.
    "The loop contains table modifications.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT standard_tab_w_sec_key ASSIGNING FIELD-SYMBOL(<fs>) TO 200.
        <fs>-comp1 = sy-tabix.
        READ TABLE standard_tab_w_sec_key TRANSPORTING NO FIELDS WITH TABLE KEY sec_key COMPONENTS comp1 = sy-tabix.
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_12_sort_itab_a.
    "A standard table declared with the standard key is sorted.
    "The sort key is explicitly specified in the SORT statement.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SORT standard_tab_w_default_key BY comp1 ASCENDING.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_12_sort_itab_z.
    "A standard table declared with the standard key is sorted.
    "The sort key is not explicitly specified in the SORT statement.
    "Instead, the standard key is used by default.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      SORT standard_tab_w_default_key.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_13_clear_free_a.
    "Clearing and populating an internal table
    "The table is cleared using a CLEAR statement.

    "Preparing demo data
    DATA str_tab_a TYPE string_table.

    DO 1000 TIMES.
      APPEND sy-tabix TO str_tab_a.
    ENDDO.
    DATA(str_tab_b) = str_tab_a.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      CLEAR str_tab_a.
      APPEND LINES OF str_tab_b TO str_tab_a.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_13_clear_free_z.
    "Clearing and populating an internal table
    "The table is cleared using a FREE statement.

    "Preparing demo data
    DATA str_tab_a TYPE string_table.

    DO 10000 TIMES.
      APPEND sy-tabix TO str_tab_a.
    ENDDO.
    DATA(str_tab_b) = str_tab_a.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      FREE str_tab_a.
      APPEND LINES OF str_tab_b TO str_tab_a.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_14_dyn_itab_spec_a.
    "READ TABLE statement using static key specifications

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      READ TABLE standard_tab_w_sec_key TRANSPORTING NO FIELDS WITH TABLE KEY sec_key COMPONENTS comp1 = sy-index.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_14_dyn_itab_spec_z.
    "READ TABLE statement using dynamic key specifications

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      READ TABLE standard_tab_w_sec_key TRANSPORTING NO FIELDS WITH TABLE KEY ('SEC_KEY') COMPONENTS ('COMP1') = sy-index.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD misc_01_while_do_a.
    "WHILE statement for comparing WHILE and DO

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      DATA num TYPE i.
      WHILE num <= 1000.
        num += 1.
      ENDWHILE.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD misc_01_while_do_z.
    "DO statement for comparing WHILE and DO

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      DATA num TYPE i.

      DO.
        num += 1.
        IF sy-index = 1000.
          EXIT.
        ENDIF.
      ENDDO.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD misc_02_strings_a.
    "Concatenating a variable-length string of type string

    DO loop_count_1000 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      DATA: str_a TYPE string,
            str_b TYPE string VALUE '#'.

      str_a &&= str_b.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD misc_02_strings_z.
    "Concatenating a fixed-length string of type c

    DO loop_count_1000 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      DATA: char_a TYPE c LENGTH 1000,
            char_b TYPE c LENGTH 1 VALUE '#'.

      char_a &&= char_b.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD misc_03_string_templates_a.
    "String specified as string literal using backquotes

    DO 5000 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      DATA str TYPE string.
      str = `ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP`.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD misc_03_string_templates_z.
    "String template only using characters, without embedded expression

    DO 5000 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      DATA str TYPE string.
      str = |ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP ABAP|.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD misc_05_type_conversion_a.
    "Calculation of numbers that share the same type

    DO loop_count_1000 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      DATA: num1   TYPE decfloat34 VALUE '1.2345',
            num2   TYPE decfloat34 VALUE '12345',
            num3   TYPE decfloat34 VALUE '12345',
            num4   TYPE decfloat34 VALUE '1.2345',
            num5   TYPE decfloat34 VALUE '1.2345',
            num6   TYPE decfloat34 VALUE '1.2345',
            result TYPE decfloat34.

      result = num1 + num2 + num3 + num4 + num5 + num6.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD misc_05_type_conversion_z.
    "Calculation of numbers that have different types triggering implicit
    "type conversions

    DO loop_count_1000 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      DATA: num1   TYPE f VALUE '1.2345',
            num2   TYPE i VALUE 12345,
            num3   TYPE int8 VALUE 12345,
            num4   TYPE p LENGTH 16 DECIMALS 8 VALUE '1.2345',
            num5   TYPE decfloat16 VALUE '1.2345',
            num6   TYPE decfloat34 VALUE '1.2345',
            result TYPE decfloat34.

      result = num1 + num2 + num3 + num4 + num5 + num6.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD meth_pass_by_ref.
    "Example method demonstrating actual parameters passed by reference

    e = a.
    f = b.
    g = c.
    h = d.
  ENDMETHOD.

  METHOD meth_pass_by_value.
    "Example method demonstrating actual parameters passed by value

    m = i.
    n = j.
    o = k.
    p = l.
  ENDMETHOD.

  METHOD misc_06_formal_parameters_a.
    "Actual parameters passed by reference

    DATA(str_tab) = VALUE string_table( ( `A` ) ( `B` ) ( `A` ) ( `P` ) ).

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      meth_pass_by_ref( a = sy-index
                        b = sy-index
                        c = str_tab
                        d = str_tab ).
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD misc_06_formal_parameters_z.
    "Actual parameters passed by value

    DATA(str_tab) = VALUE string_table( ( `A` ) ( `B` ) ( `A` ) ( `P` ) ).

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      meth_pass_by_value( i = sy-index
                          j = sy-index
                          k = str_tab
                          l = str_tab ).
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD misc_07_parallel_processing_a.
    "Demonstrating parallelization using the cl_abap_parallel class
    "The implementation includes inserting many entries to a database
    "table, executed in parallel. Then, the added entries are retrieved.
    "The inserted data contains a time stamp of the insertion.
    "The runtime delta of the first and last inserted entry is calculated
    "using cl_abap_tstmp=>subtract.

    DATA ref_tab TYPE cl_abap_parallel=>t_in_inst_tab.

    DO loop_count_5 TIMES.
      DATA(inst) = NEW lcl_parallel( ).
      APPEND inst TO ref_tab.
    ENDDO.

    DATA(parallel) = NEW cl_abap_parallel( ).

    parallel->run_inst( EXPORTING p_in_tab  = ref_tab
                        IMPORTING p_out_tab = DATA(result_info) ).

    SELECT id, num1, crea_date_time
      FROM zdemo_abap_tabca
      WHERE num1 = 1
      ORDER BY crea_date_time ASCENDING
      INTO TABLE @DATA(it).

    out->write( name ).
    IF lines( it ) < 250.
      out->write( `Not all database entries were written.` ).
      out->write( |Table lines with value num1 = 1: { lines( it ) }| ).
    ELSE.
      DATA(timestamp1) = it[ 1 ]-crea_date_time.
      DATA(timestamp2) = it[ lines( it ) ]-crea_date_time.

      DATA(diff) = cl_abap_tstmp=>subtract(
            tstmp1 = timestamp2
            tstmp2 = timestamp1 ).

      out->write( |{ diff STYLE = SIMPLE }| ).
      out->write( |Table lines with value num1 = 1: { lines( it ) }| ).
    ENDIF.
  ENDMETHOD.

  METHOD misc_07_parallel_processing_z.
    "Sequential processing in contrast to the parallel processing
    "The implementation includes inserting many entries to a database
    "table, executed in parallel. Then, the added entries are retrieved.
    "The inserted data contains a time stamp of the insertion.
    "The runtime delta of the first and last inserted entry is calculated
    "using cl_abap_tstmp=>subtract.

    DATA(inst) = NEW lcl_parallel( ).
    DO loop_count_5 TIMES.
      inst->meth( ).
    ENDDO.

    SELECT id, num1, crea_date_time
      FROM zdemo_abap_tabca
      WHERE num1 = 2
      ORDER BY crea_date_time ASCENDING
      INTO TABLE @DATA(it).

    out->write( name ).
    IF lines( it ) < 250.
      out->write( `Not all database entries were written.` ).
      out->write( |Table lines with value num1 = 2: { lines( it ) }| ).
    ELSE.
      DATA(timestamp1) = it[ 1 ]-crea_date_time.
      DATA(timestamp2) = it[ lines( it ) ]-crea_date_time.

      DATA(diff) = cl_abap_tstmp=>subtract(
            tstmp1 = timestamp2
            tstmp2 = timestamp1 ).

      out->write( |{ diff STYLE = SIMPLE }| ).
      out->write( |Table lines with value num2 = 2: { lines( it ) }| ).
    ENDIF.
  ENDMETHOD.

  METHOD itab_15_read_where_a.
    "READ TABLE ... WITH KEY as an alternative to a READ TABLE ... WHERE statement

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      READ TABLE sorted_tab TRANSPORTING NO FIELDS WITH KEY comp5 = sy-index.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_15_read_where_z.
    "READ TABLE ... WHERE statement, which can also be expressed by specifying a key
    "using a READ TABLE ... WITH KEY statement.
    "Without the pragma, a syntax warning would be displayed informing about performance
    "issues with the statement.

    DO loop_count_500 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      READ TABLE sorted_tab TRANSPORTING NO FIELDS WHERE comp5 = sy-index ##read_where_ok.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_16_find_replace_table_a.
    "FIND IN TABLE and REPLACE IN TABLE statements to perform block-wise operations
    "in an internal table with character-like line type

    "Populating demo table
    DATA str_tab TYPE string_table.
    DO 100 TIMES.
      APPEND |ABP{ sy-index }| TO str_tab.
    ENDDO.
    DATA(str_tab_copy) = str_tab.

    DO loop_count_50 TIMES.
      str_tab = str_tab_copy.
      ts1 = utclong_current( ).
**********************************************************************
      FIND ALL OCCURRENCES OF `ABP`
        IN TABLE str_tab
        RESULTS DATA(res_tab)
        RESPECTING CASE.

      REPLACE ALL OCCURRENCES OF `ABP`
        IN TABLE str_tab
        WITH `ABAP`
        RESPECTING CASE.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD itab_16_find_replace_table_z.
    "Line by line search and replacement in an internal table
    "with character-like line type

    "Populating demo table
    DATA str_tab TYPE string_table.
    DO loop_count_50 TIMES.
      APPEND |ABP{ sy-index }| TO str_tab.
    ENDDO.
    DATA(str_tab_copy) = str_tab.

    DO loop_count_500 TIMES.
      str_tab = str_tab_copy.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT str_tab ASSIGNING FIELD-SYMBOL(<fs>).
        FIND ALL OCCURRENCES OF `ABP`
          IN <fs>
          RESULTS DATA(res_tab)
          RESPECTING CASE.
      ENDLOOP.

      LOOP AT str_tab ASSIGNING <fs>.
        REPLACE ALL OCCURRENCES OF `ABP`
          IN TABLE str_tab
          WITH `ABAP`
          RESPECTING CASE.
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD eml_01_eml_in_loop_a.
    "EML update request using a FOR loop for a block-wise operation

    DATA read_result TYPE TABLE FOR READ RESULT zdemo_abap_rap_ro_m\\root.
    DO loop_count_5 TIMES.
      APPEND VALUE #( key_field = sy-index field3 = sy-index field4 = sy-index ) TO read_result.
    ENDDO.

    DO loop_count_5 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      MODIFY ENTITIES OF zdemo_abap_rap_ro_m
        ENTITY root
        UPDATE FIELDS ( field3 field4 ) WITH VALUE #( FOR key IN read_result ( %tky   = key-%tky
                                                                               field3 = key-field3 + 1
                                                                               field4 = key-field4 + 1 ) ).
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD eml_01_eml_in_loop_z.
    "Multiple individual EML update requests in a loop

    DATA result TYPE TABLE FOR READ RESULT zdemo_abap_rap_ro_m\\root.
    DO loop_count_5 TIMES.
      APPEND VALUE #( key_field = sy-index field3 = sy-index field4 = sy-index ) TO result.
    ENDDO.
    DATA upd TYPE TABLE FOR UPDATE zdemo_abap_rap_ro_m\\root.
    upd = VALUE #( FOR wa IN result ( %tky = wa-%tky field3 = wa-field3 + 1 field4 = wa-field4 + 1 ) ).

    DO loop_count_5 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      LOOP AT upd ASSIGNING FIELD-SYMBOL(<fs>).
        MODIFY ENTITIES OF zdemo_abap_rap_ro_m
         ENTITY root
         UPDATE FIELDS ( field3 field4 ) WITH VALUE #( ( <fs> ) ).
      ENDLOOP.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD misc_04_search_pattern_a.
  "Simple pattern-based search using IF and CP
  DATA(str) = `abc_def_ghi`.

  DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      IF str CP `*f#_*`.
       ...
      ENDIF.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

  METHOD misc_04_search_pattern_z.
  "Using FIND and a regular expression

  DATA(str) = `abc_def_ghi`.

  DO loop_count_50 TIMES.
      ts1 = utclong_current( ).
**********************************************************************
      FIND PCRE `.*f_.*` in str.

      IF sy-subrc = 0.
       ...
      ENDIF.
**********************************************************************
      store_runtime( high = utclong_current( ) low = ts1 ).
    ENDDO.

    runtime = get_avg_runtime( ).
    out->write( name ).
    out->write( |{ runtime STYLE = SIMPLE }| ).
  ENDMETHOD.

ENDCLASS.

CCIMP include (Local Types tab in ADT)

CLASS lcl_parallel DEFINITION.
  PUBLIC SECTION.
    INTERFACES if_abap_parallel.
    METHODS meth.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS lcl_parallel IMPLEMENTATION.
  METHOD if_abap_parallel~do.
    DATA ts_long TYPE timestampl.
    DO 50 TIMES.
      GET TIME STAMP FIELD ts_long.
      "Suboptimal database table insertion in a loop serving the example demonstration purpose
      INSERT zdemo_abap_tabca FROM @( VALUE #( id = xco_cp=>uuid( )->value num1 = 1 crea_date_time = ts_long ) ).
    ENDDO.
  ENDMETHOD.

  METHOD meth.
    DATA ts_long TYPE timestampl.
    DO 50 TIMES.
      GET TIME STAMP FIELD ts_long.
      "Suboptimal database table insertion in a loop serving the example demonstration purpose
      INSERT zdemo_abap_tabca FROM @( VALUE #( id = xco_cp=>uuid( )->value num1 = 2 crea_date_time = ts_long ) ).
    ENDDO.
  ENDMETHOD.
ENDCLASS.

⬆️ back to top