Skip to Content

Yes, it’s possible.

Dear community,

Performance vs dynamic. I have always been under the impression that if we create a dynamic table we will not be able to access it in a fast way. Or in other words, I didn’t think it was possible to create a sorted or hashed dynamic table.

But now I know this is not true, and I want to share it with you.

 

The test case

I have created a small program to create a dynamic table with the key fields from SBOOK and a few fields more. Select all data from SBOOK into the dynamic table with the sorted key, and also another dynamic table without key fields (standard table). Analyzed the access time with ST12.

And here is the result, accessing one of them is 100 times faster than the other. I’ll let you guess which one.

 

The code

Here’s the code so you can execute the example yourself, and also check how to create the dynamic table with a sorted or hashed key.

Enjoy.

*&---------------------------------------------------------------------*
*& Report  YTMP_DYN_TAB_W_KEYS
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT ytmp_dyn_tab_w_keys.


START-OF-SELECTION.

  DATA table_w_keys_handle TYPE REF TO cl_abap_tabledescr.
  DATA keyless_table_handle TYPE REF TO cl_abap_tabledescr.
  DATA keys TYPE abap_table_keydescr_tab.
  DATA struct_desc  TYPE REF TO cl_abap_structdescr.
  DATA table_w_keys TYPE REF TO data.
  DATA keyless_table TYPE REF TO data.

  PERFORM get_struct
    CHANGING
      struct_desc.

  PERFORM get_keys
    CHANGING
      keys.

  cl_abap_tabledescr=>create_with_keys(
    EXPORTING
      p_line_type          = struct_desc    " Type Description Object of Row Type of Table
      p_keys               = keys    " Table Keys
    RECEIVING
      p_result             = table_w_keys_handle    " Type Description Object of Table
  ).
  CREATE DATA table_w_keys TYPE HANDLE table_w_keys_handle.

  cl_abap_tabledescr=>create(
    EXPORTING
      p_line_type          = struct_desc    " Line Type
    RECEIVING
      p_result             = keyless_table_handle    " Result Type
  ).
  CREATE DATA keyless_table TYPE HANDLE keyless_table_handle.

  PERFORM select_data
    CHANGING table_w_keys.

  PERFORM select_data
    CHANGING keyless_table.

  PERFORM read_with_key
    USING table_w_keys.

  PERFORM read_wo_key
    USING keyless_table.

  WRITE 'Done'.

*&---------------------------------------------------------------------*
*&      Form  GET_STRUCT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_STRUCT_DESC  text
*----------------------------------------------------------------------*
FORM get_struct
  CHANGING
    ch_struct_desc TYPE REF TO cl_abap_structdescr.

  DATA fields TYPE abap_component_tab.
  DATA field LIKE LINE OF fields.

  field-name = 'CARRID'.
  field-type ?= cl_abap_datadescr=>describe_by_name( p_name = 'S_CARR_ID' ).
  APPEND field TO fields.

  field-name = 'CONNID'.
  field-type ?= cl_abap_datadescr=>describe_by_name( p_name = 'S_CONN_ID' ).
  APPEND field TO fields.

  field-name = 'FLDATE'.
  field-type ?= cl_abap_datadescr=>describe_by_name( p_name = 'S_DATE' ).
  APPEND field TO fields.

  field-name = 'BOOKID'.
  field-type ?= cl_abap_datadescr=>describe_by_name( p_name = 'S_BOOK_ID' ).
  APPEND field TO fields.

  field-name = 'SMOKER'.
  field-type ?= cl_abap_datadescr=>describe_by_name( p_name = 'S_SMOKER' ).
  APPEND field TO fields.

  field-name = 'CLASS'.
  field-type ?= cl_abap_datadescr=>describe_by_name( p_name = 'S_CLASS' ).
  APPEND field TO fields.

  ch_struct_desc ?= cl_abap_structdescr=>create(
        p_components = fields
    ).

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  GET_KEYS
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_KEYS  text
*----------------------------------------------------------------------*
FORM get_keys
  CHANGING
    ch_keys TYPE abap_table_keydescr_tab.

  DATA key LIKE LINE OF ch_keys.
  DATA component LIKE LINE OF key-components.

  component-name = 'CARRID'.
  APPEND component TO key-components.

  component-name = 'CONNID'.
  APPEND component TO key-components.

  component-name = 'FLDATE'.
  APPEND component TO key-components.

  component-name = 'BOOKID'.
  APPEND component TO key-components.

  key-name = 'MY_KEY'.
  key-is_primary = abap_true.
  key-is_unique = abap_true.
  key-access_kind = cl_abap_tabledescr=>tablekind_sorted.
  key-key_kind = cl_abap_tabledescr=>keydefkind_user.

  APPEND key TO ch_keys.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  SELECT_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_TABLE_W_KEYS  text
*----------------------------------------------------------------------*
FORM select_data
  CHANGING
    ch_table_w_keys TYPE REF TO data.

  FIELD-SYMBOLS <any_table> TYPE ANY TABLE.

  ASSIGN ch_table_w_keys->* TO <any_table>.

  SELECT * FROM sbook
    INTO CORRESPONDING FIELDS OF TABLE <any_table>.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  READ_WITH_KEY
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_TABLE_W_KEYS  text
*----------------------------------------------------------------------*
FORM read_with_key
  USING
    im_table_w_keys TYPE REF TO data.

  FIELD-SYMBOLS <any_table> TYPE ANY TABLE.

  ASSIGN im_table_w_keys->* TO <any_table>.

  READ TABLE <any_table> TRANSPORTING NO FIELDS
    WITH TABLE KEY ('CARRID') = 'SQ'
                   ('CONNID') = '0002'
                   ('FLDATE') = '20170915'
                   ('BOOKID') = '00000002'.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  READ_WO_KEY
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_KEYLESS_TABLE  text
*----------------------------------------------------------------------*
FORM read_wo_key
  USING
    im_keyless_table TYPE REF TO data.

  FIELD-SYMBOLS <any_table> TYPE ANY TABLE.

  ASSIGN im_keyless_table->* TO <any_table>.

  READ TABLE <any_table> TRANSPORTING NO FIELDS
    WITH KEY ('CARRID') = 'SQ'
             ('CONNID') = '0002'
             ('FLDATE') = '20170915'
             ('BOOKID') = '00000002'.

ENDFORM.
To report this post you need to login first.

9 Comments

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

    1. Bruno Esperança Post author

      Thank you Michelle,

      For a very long time now, I have totally avoided using standard tables. It’s so easy to create a sorted table with a non-unique key, that really there’s no excuse not to use it 🙂

      Also, generally we should avoid dynamic programming as much as possible, as it is slower and more error prone, but if you should find a situation where there’s no alternative, I hope this will help you make it fast 🙂

      Cheers,
      Bruno

      (2) 
      1. Michelle Crapo

        When I use dynamic programming – I always used a standard table.  Honestly – I didn’t think of using anything else.

        And yes, I avoid it.  Basically just because of the KISS principle.  I always try to keep my programs simple.

        Michelle

        (2) 
    2. Bruno Esperança Post author

      PS: The “read” statement I show above is also very “static”, but it’s possible to completely dynamically get the keys you are interested for, and read using this key. If you try to do this and have trouble, let me know, I can help.

      (1) 
    1. Uladzislau Pralat

      Hi Jelena,

      anywhere where you need to access large dynamic table fast e.g. sorted table accessed by key.

      Pros: performance optimazation

      Cons: more complex logic (think twice if dynamic programming is unavoidable).

      Regards, Uladzislau

       

      (0) 
    2. Bruno Esperança Post author

      Hi Jelena,

      My pleasure.

      Generally, I avoid dynamic programming like the devil avoids the cross. But sometimes there’s no other way. One example I’ve had of this was a requirement I had to do some processing with the condition key tables (AXXX). These tables have a structure that is defined via customizing, so as far as I know, the structure has to be read dynamically. We can also get the keys from the table definition, we present the keys to the user and ask which entries they wish to change, and then do our processing (this is actually very close to what I had to implement).

      The pros are obvious.

      As for the cons, as I mentioned to Michelle, I have been using nothing but sorted and hashed tables for a long time now, and never really encountered a con that would make me say “oh ok so maybe a standard table here is better”.

      Cheers!

      (2) 
      1. Jelena Perfiljeva

        Thank you, Bruno! A… tables is exactly what I thought of but wasn’t sure. Even though they are indeed driven by customizing, I haven’t really seen anyone access them dynamically in the custom reports. Usually an assumption is made that the table won’t change after it’s created. Which is probably not a good idea.

        Thanks again!

         

        (0) 
        1. Bruno Esperança Post author

          If it were only a few tables, maybe I would have tried to push for something “static”, and clearly document that the structure of the tables could not be changed. However, the requirement was to allow users to process *any* of those tables, so a static solution was not practical.

          You are very welcome, I hope it will be useful for you at some point.

          Cheers 🙂

          (1) 

Leave a Reply