Skip to Content
Author's profile photo Siddharth Shah

Performance Impact due to Memory Allocation

Hi All,

Memory plays important role in performance of the program. I am writing this blog to explain why we should give equal importance to memory we are allocating to variables/internal tables.

Lets say I have fetched 100000 records from BSEG table and stored in one internal table (say LT_BSEG). As soon as I gets 100000 records into LT_BSEG table, LT_BSEG internal table gets allocated with required memory.

select * from bseg into table @data(lt_bseg) UP TO 100000 rows.

 

Now I am processing this 100000 records and calculating how much time it takes.

loop at lt_bseg ASSIGNING FIELD-SYMBOL(<lfs_bseg>).
  <lfs_bseg>-sgtxt = 'Changing Text Value'.
ENDLOOP.

GET TIME STAMP FIELD lv_t2.

lv_diff1 = lv_t2 - lv_t1.

On second instance I am copying LT_BSEG to another internal table LT_BSEG_COPY. As soon as i am copying, further memory gets allocated to LT_BSEG_COPY.

At this time, I have got memory allocated for two Internal tables having 100000 rows each.

Now I am processing same 100000 records again and calculating how much time it takes.

data(lt_bseg_copy) = lt_bseg[].
GET TIME STAMP FIELD lv_t1.

loop at lt_bseg ASSIGNING <lfs_bseg>.
  <lfs_bseg>-sgtxt = 'Changing Text Value'.
ENDLOOP.

GET TIME STAMP FIELD lv_t2.

lv_diff2 = lv_t2 - lv_t1.

lv_percentage =  ( lv_diff2   / lv_diff1 ) .

On Third instance I am FREEing memory from unwanted internal table (LT_BSEG_COPY) and does same processing on those 100000 records and calculating how much time it takes.

 

********************************
****** FREEing Memory *********
********************************
FREE lt_bseg_copy.
loop at lt_bseg ASSIGNING <lfs_bseg>.
  <lfs_bseg>-sgtxt = 'Changing Text Value'.
ENDLOOP.

GET TIME STAMP FIELD lv_t2.

lv_diff3 = lv_t2 - lv_t1.

 

I have got 6 times impact on performance when I copied internal table to another internal table and processed same number of rows.

 

Code:

DATA:      lv_t1    TYPE timestampl,
           lv_t2    TYPE timestampl,
           lv_diff1        type p DECIMALS 2,
           lv_diff2        type p DECIMALS 2,
           lv_diff3        type p DECIMALS 2,
           lv_percentage        type i.

select * from bseg into table @data(lt_bseg) UP TO 100000 rows.


cl_demo_output=>begin_section( | Processing Internal table having { lines( lt_bseg ) } rows |  ).
*********************************************************
****** Memory Allocated to One Internal Table *********
*********************************************************
cl_demo_output=>begin_section( |Memory Allocated to one internal table | ).

GET TIME STAMP FIELD lv_t1.

loop at lt_bseg ASSIGNING FIELD-SYMBOL(<lfs_bseg>).
  <lfs_bseg>-sgtxt = 'Changing Text Value'.
ENDLOOP.

GET TIME STAMP FIELD lv_t2.

lv_diff1 = lv_t2 - lv_t1.

cl_demo_output=>write_text( |Time Taken to process { lines( lt_bseg ) } rows is - { lv_diff1 }|  ).

*********************************************************
****** Memory Allocated to TWO Internal Tables *********
************ ITAB COPY *********************************
*********************************************************
data(lt_bseg_copy) = lt_bseg[].

cl_demo_output=>begin_section( | Memory Allocated to two internal table | ).

GET TIME STAMP FIELD lv_t1.

loop at lt_bseg ASSIGNING <lfs_bseg>.
  <lfs_bseg>-sgtxt = 'Test'.
ENDLOOP.

GET TIME STAMP FIELD lv_t2.

lv_diff2 = lv_t2 - lv_t1.

cl_demo_output=>write_text( |Time Taken to process { lines( lt_bseg ) } rows is - { lv_diff2 }|  ).

lv_percentage =  ( lv_diff2   / lv_diff1 ) .
cl_demo_output=>write_text( |Performance decreased by { lv_percentage } times | ).


********************************
****** FREEing Memory *********
********************************
FREE lt_bseg_copy.

cl_demo_output=>begin_section( |Deallocating memory from one of the internal table|  ).
GET TIME STAMP FIELD lv_t1.

loop at lt_bseg ASSIGNING <lfs_bseg>.
  <lfs_bseg>-sgtxt = 'Test'.
ENDLOOP.

GET TIME STAMP FIELD lv_t2.

lv_diff3 = lv_t2 - lv_t1.

cl_demo_output=>write_text( |Time Taken to process { lines( lt_bseg ) } rows is - { lv_diff3 }|  ).
lv_percentage =  ( lv_diff2   / lv_diff3 ) .
cl_demo_output=>write_text( |Performance again increased by { lv_percentage } times| ).


cl_demo_output=>display( ).

 

Output:

Assigned Tags

      2 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Shai Sinai
      Shai Sinai

      Thanks for sharing your experience.
      However, I think that your analysis is incorrect.
      Internal tables have special mechanism of sharing (Memory of two internal tables is shared until first table is being modified).
      Hence, your second measurement was result of initial (real) memory allocation of second internal table and not impact of global memory allocation.

      You can check this by modifying internal table before your second loop/measurement (with lt_bseg[ 1 ]-sgtxt = 'Test', for example).

      Author's profile photo Siddharth Shah
      Siddharth Shah
      Blog Post Author

      Thanks Shai.

      Yes you are right, result was result of second internal tale memory due to copy.

      We many times copy one internal table to another internal table. This copy of internal table should be avoided as much as possible else it impacts performance.

       

      Regards,

      Siddharth Shah