Skip to Content

I construct three internal tables with different table types:


/wp-content/uploads/2015/12/clipboard1_854790.png

The complete test source code could be found in the end part of the blog.

insert operation comparison

The hashed table is least efficient since additional overhead is paid to maintain the internal administrative information for hash logic.

The standard table is fastest due to the fact that there is no overhead.

/wp-content/uploads/2015/12/clipboard2_854791.png

read operation comparison

The standard table read is slowest due to o(n) complexity.

/wp-content/uploads/2015/12/clipboard3_854792.png

If we exclude the standard table read and compare the left three, it is clear the hashed table read is most efficient.

/wp-content/uploads/2015/12/clipboard4_854793.png

The complete test source code:


REPORT z.
PARAMETERS: count TYPE i OBLIGATORY DEFAULT 1000.
TYPES: BEGIN OF ty_pair,
         key   TYPE i,
         value TYPE string,
       END OF ty_pair.
TYPES: tt_standard TYPE STANDARD TABLE OF ty_pair WITH KEY key,
       tt_sorted   TYPE SORTED TABLE OF ty_pair WITH UNIQUE KEY key,
       tt_hashed   TYPE HASHED TABLE OF ty_pair WITH UNIQUE KEY key.
DATA: lv_start    TYPE i,
      lv_end      TYPE i,
      lt_standard TYPE tt_standard,
      lt_sorted   TYPE tt_sorted,
      lt_hashed   TYPE tt_hashed,
      lv_size        TYPE i.
START-OF-SELECTION.
  lv_size = count.
  PERFORM insert_standard.
  PERFORM insert_sorted.
  PERFORM insert_hashed.
  PERFORM read_standard.
  PERFORM read_standard_binary.
  PERFORM read_sorted.
  PERFORM read_hashed.
FORM insert_standard.
  PERFORM start_timer.
  DO lv_size TIMES.
    DATA(line) = VALUE ty_pair( key = sy-index value = sy-index ).
    APPEND line TO lt_standard.
  ENDDO.
  PERFORM stop_timer.
  " WRITE: / 'standard table insertion: ' , lv_end.
ENDFORM.
FORM insert_sorted.
  PERFORM start_timer.
  DO lv_size TIMES.
    DATA(line) = VALUE ty_pair( key = sy-index value = sy-index ).
    INSERT line INTO TABLE lt_sorted.
  ENDDO.
  PERFORM stop_timer.
  " WRITE: / 'sorted table insertion: ' , lv_end.
ENDFORM.
FORM insert_hashed.
  PERFORM start_timer.
  DO lv_size TIMES.
    DATA(line) = VALUE ty_pair( key = sy-index value = sy-index ).
    INSERT line INTO TABLE lt_hashed.
  ENDDO.
  PERFORM stop_timer.
  " WRITE: / 'hashed table insertion: ' , lv_end.
ENDFORM.
FORM read_standard.
  PERFORM start_timer.
  DO lv_size TIMES.
    READ TABLE lt_standard ASSIGNING FIELD-SYMBOL(<standard>) WITH KEY key = sy-index.
    ASSERT sy-subrc = 0.
  ENDDO.
  PERFORM stop_timer.
  WRITE:/ 'standard table read: ', lv_end.
ENDFORM.
FORM read_standard_binary.
  SORT lt_standard BY key.
  PERFORM start_timer.
  DO lv_size TIMES.
    READ TABLE lt_standard ASSIGNING FIELD-SYMBOL(<standard>) WITH KEY key = sy-index BINARY SEARCH.
    ASSERT sy-subrc = 0.
  ENDDO.
  PERFORM stop_timer.
  WRITE:/ 'standard table binary read: ', lv_end.
ENDFORM.
FORM read_sorted.
  PERFORM start_timer.
  DO lv_size TIMES.
    READ TABLE lt_sorted ASSIGNING FIELD-SYMBOL(<sorted>) WITH KEY key = sy-index.
    ASSERT sy-subrc = 0.
  ENDDO.
  PERFORM stop_timer.
  WRITE:/ 'sorted table read: ', lv_end.
ENDFORM.
FORM read_hashed.
  PERFORM start_timer.
  DO lv_size TIMES.
    READ TABLE lt_hashed ASSIGNING FIELD-SYMBOL(<sorted>) WITH TABLE KEY key = sy-index.
    ASSERT sy-subrc = 0.
  ENDDO.
  PERFORM stop_timer.
  WRITE:/ 'hashed table read: ', lv_end.
ENDFORM.
FORM start_timer.
  CLEAR: lv_start, lv_end.
  GET RUN TIME FIELD lv_start.
ENDFORM.
FORM stop_timer.
  GET RUN TIME FIELD lv_end.
  lv_end = lv_end - lv_start.
ENDFORM.
To report this post you need to login first.

1 Comment

You must be Logged on to comment or reply to a post.

  1. Jacques Nomssi

    Hello Jerry,

    I will repeat myself by proposing order-of-growth estimation based on the doubling hypothesis: The running time T as a function of the number of rows N is described as power law  T(N) = c N^x, c is a constant. x is then determined by comparing T(N) with T(2N) as log( T(2N) / T(N) ) / log( 2 ). I once try using this in an unit test.


        METHOD profile.

        CLEAR rs_time.

        rs_time-size = iv_size.

        DATA(lv_start) = mi_timer->get_runtime( ).

        run_data( iv_size ).

        rs_time-time = mi_timer->get_runtime( ) - lv_start.

        IF iv_time GT 0.

          rs_time-lg_ratio = log10( rs_time-time / iv_time ).

        ENDIF.

      ENDMETHOD.                    "profile

      METHOD performance.

    *   empirical analysis

        CONSTANTS c_precision TYPE f VALUE '1e-2'.

        DATA lv_size TYPE syindex VALUE 1.

        mi_timer = cl_abap_runtime=>create_hr_timer( ).

        DATA(ls_time) = profile( iv_size = 0

                                 iv_time = 0 ).

        DO 6 TIMES.

          ls_time = profile( iv_size = lv_size

                             iv_time = ls_time-time ).

          lv_size = lv_size * 10.

        ENDDO.

        IF ( ls_time-lg_ratio - c_precision )  > 1 .

          cl_abap_unit_assert=>fail( msg = | Performance: { ls_time-lg_ratio } | ).

        ENDIF.

      ENDMETHOD.

    best regards,

    JNN

    (0) 

Leave a Reply