Skip to content

Instantly share code, notes, and snippets.

@softy12
Last active February 21, 2023 03:42
Show Gist options
  • Save softy12/34b44fdd47d348c310f7692537aae696 to your computer and use it in GitHub Desktop.
Save softy12/34b44fdd47d348c310f7692537aae696 to your computer and use it in GitHub Desktop.
replacing LOOP with ABAP Filter Operator
PROGRAM zmm_loop_replacement.
CLASS zcl_loop_replacement DEFINITION.
PUBLIC SECTION.
TYPES t_output TYPE TABLE OF string.
CLASS-METHODS:
run EXPORTING output TYPE t_output.
ENDCLASS.
CLASS zcl_loop_replacement IMPLEMENTATION.
METHOD run.
TYPES: BEGIN OF data_type,
col_1(3) TYPE c,
col_f TYPE i,
END OF data_type.
DATA: t_data TYPE TABLE OF data_type,
t_data1 TYPE TABLE OF data_type,
t_data3 TYPE TABLE OF data_type,
th_data TYPE SORTED TABLE OF data_type WITH NON-UNIQUE KEY col_1,
s_data TYPE data_type,
v_count TYPE i.
DATA(o_timer) = cl_abap_runtime=>create_hr_timer( ).
DATA(r_random) = cl_abap_random_int=>create( seed = CONV i( sy-uzeit )
min = 1
max = 100 ).
* prefill some dummy data to base itab
s_data = VALUE #( BASE s_data col_1 = 'AAA' ).
DO 200000 TIMES.
s_data-col_f = r_random->get_next( ).
INSERT s_data INTO TABLE t_data.
ENDDO.
s_data = VALUE #( BASE s_data col_1 = 'BBB' ).
DO 200000 TIMES.
s_data-col_f = r_random->get_next( ).
INSERT s_data INTO TABLE t_data.
ENDDO.
th_data = t_data.
* run 1: classic LOOP with WHERE
DATA(t_start) = o_timer->get_runtime( ).
LOOP AT t_data INTO s_data WHERE ( col_1 = 'AAA' ).
INSERT s_data INTO TABLE t_data1.
ENDLOOP.
DATA(msec) = CONV decfloat16( o_timer->get_runtime( ) - t_start ) / 1000000.
v_count = REDUCE i( INIT n = 0 FOR x_data IN t_data1 NEXT n = n + 1 ).
APPEND `itab1, count: ` && v_count TO output.
v_count = REDUCE i( INIT n = 0 FOR x_data IN t_data1 NEXT n = n + x_data-col_f ).
APPEND `itab1, total: ` && v_count TO output.
APPEND `run no 1 - LOOP: ` && msec TO output.
* run 2: FILTER operator
t_start = o_timer->get_runtime( ).
DATA(t_data2) = FILTER #( th_data WHERE col_1 = 'AAA' ).
msec = CONV decfloat16( o_timer->get_runtime( ) - t_start ) / 1000000.
v_count = REDUCE i( INIT n = 0 FOR x_data IN t_data2 NEXT n = n + 1 ).
APPEND `itab2, count: ` && v_count TO output.
v_count = REDUCE i( INIT n = 0 FOR x_data IN t_data2 NEXT n = n + x_data-col_f ).
APPEND `itab2, total: ` && v_count TO output.
APPEND `run no 2 - FILTER: ` && msec TO output.
TYPES: BEGIN OF filter_type,
col_1(3) TYPE c,
END OF filter_type.
DATA: th_filter TYPE HASHED TABLE OF filter_type WITH UNIQUE DEFAULT KEY,
s_filter TYPE filter_type,
t_filter TYPE rssb_t_range.
* prefill filter itab/range
th_filter = VALUE #( BASE th_filter ( col_1 = 'AAA' ) ).
t_filter = VALUE #( BASE t_filter ( opt = 'EQ' sign = 'I' low = 'AAA' ) ).
* run 3: classic LOOP with WHERE condition into range
t_start = o_timer->get_runtime( ).
LOOP AT th_data INTO s_data WHERE col_1 IN t_filter.
INSERT s_data INTO TABLE t_data3.
ENDLOOP.
msec = CONV decfloat16( o_timer->get_runtime( ) - t_start ) / 1000000..
v_count = REDUCE i( INIT n = 0 FOR x_data IN t_data3 NEXT n = n + 1 ).
APPEND `itab3, count: ` && v_count TO output.
v_count = REDUCE i( INIT n = 0 FOR x_data IN t_data3 NEXT n = n + x_data-col_f ).
APPEND `itab3, total: ` && v_count TO output.
APPEND `run no 3 - LOOP w itab: ` && msec TO output.
* run 4: FILTER operator with filter as itab
t_start = o_timer->get_runtime( ).
DATA(t_data4) = FILTER #( th_data IN th_filter WHERE col_1 = col_1 ).
msec = CONV decfloat16( o_timer->get_runtime( ) - t_start ) / 1000000.
v_count = REDUCE i( INIT n = 0 FOR x_data IN t_data4 NEXT n = n + 1 ).
APPEND `itab4, count: ` && v_count TO output.
v_count = REDUCE i( INIT n = 0 FOR x_data IN t_data4 NEXT n = n + x_data-col_f ).
APPEND `itab4, total: ` && v_count TO output.
APPEND `run no 4 - FILTER w itab: ` && msec TO output.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA t_output TYPE TABLE OF string.
zcl_loop_replacement=>run( IMPORTING output = t_output ).
cl_demo_output=>display( t_output ).
@softy12
Copy link
Author

softy12 commented Jul 29, 2022

An quick attempt to replace ABAP classing LOOP statement with ABAP Filter Operator.
All for all 4 cases are measured for a runtime. Also a check of particular itabs no of entries is performed on top of sum of column col_f that is populated by randomly generated values.
The fastest one seems to be a case (no 2) of the ABAP Filter Operator where a condition is hardcoded in the filter it self.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment