APPEND 성능 비교 (value for, loop, move 등)
VALUE FOR, LOOP APPEND, MOVE
Internal Table의 일부 필드값을 Range로 만들 경우 편리함 때문에 요즘에는 계속 value for만 사용하고 있었는데,
문득 동일한 데이터를 Append 할때 loop append가 빠른지 value for가 빠른지 궁금하여 실험을 해봤습니다.
나름대로 여러가지를 테스트 해봤는데. 어마어마한 차이는 없는듯 합니다.
그나마 단순히 A itab을 B itab으로 복사할 경우 move-corresponding이 압도적으로 빠르고
조건에 따라 필터링해서 데이터를 복사할 경우 value for assigning이 조금이라도 더 빨랐습니다.
그리고, 모든 경우에서 into 보다 assigning이 조금이라도 더 빠릅니다.
아무래도 Internal Table의 특정 레코드의 데이터를 wa로 복사하는 into 보다는 주소값만 가지고 있는 assigning이 성능 면에서는 더 효과적인 듯 합니다.
# 소스코드
REPORT yappend_who_is_best LINE-SIZE 500.
TYPES: BEGIN OF ts_result,
step TYPE i,
category TYPE string,
text TYPE string,
rtime TYPE i,
rtime_unit TYPE string,
END OF ts_result,
tt_result TYPE STANDARD TABLE OF ts_result WITH EMPTY KEY.
DATA: lt_temp TYPE STANDARD TABLE OF dd03l,
ls_temp LIKE LINE OF lt_temp.
DATA: lt_itab TYPE RANGE OF dd03l-fieldname,
ls_itab LIKE LINE OF lt_itab,
lt_itab2 TYPE STANDARD TABLE OF dd03l.
DATA: lv_rtime TYPE i,
lt_result TYPE tt_result.
PARAMETERS p_count TYPE i OBLIGATORY DEFAULT 1000000.
START-OF-SELECTION.
FREE : lt_itab, lt_temp, lt_result.
SELECT
fieldname
FROM dd03l
UP TO @p_count ROWS
INTO CORRESPONDING FIELDS OF TABLE @lt_temp.
* DO p_count TIMES.
* CALL FUNCTION 'GENERAL_GET_RANDOM_STRING'
* EXPORTING
* number_chars = 5
* IMPORTING
* random_string = lv_string.
* MOVE: lv_string TO ls_temp-key1. CONDENSE ls_temp-key1.
* ls_temp-key1 = ls_temp-key1 && sy-tabix.
* APPEND ls_temp TO lt_temp.
* ENDDO.
"Directly appending
"VALUE FOR
FREE lt_itab2.
GET RUN TIME FIELD lv_rtime.
lt_itab2 = VALUE #( FOR ls1 IN lt_temp
( ls1 ) ).
PERFORM determine_write USING 'Directly Appending' 'VALUE FOR - INTO'
lv_rtime.
FREE lt_itab2.
GET RUN TIME FIELD lv_rtime.
lt_itab2 = VALUE #( FOR <lfs1> IN lt_temp
( <lfs1> ) ).
PERFORM determine_write USING 'Directly Appending' 'VALUE FOR - ASSIGNING'
lv_rtime.
"LOOP
FREE lt_itab2.
GET RUN TIME FIELD lv_rtime.
LOOP AT lt_temp INTO DATA(ls_temp1).
APPEND ls_temp1 TO lt_itab2.
ENDLOOP.
PERFORM determine_write USING 'Directly Appending' 'LOOP - INTO'
lv_rtime.
FREE lt_itab2.
GET RUN TIME FIELD lv_rtime.
LOOP AT lt_temp ASSIGNING FIELD-SYMBOL(<lfs_temp>).
APPEND <lfs_temp> TO lt_itab2.
ENDLOOP.
PERFORM determine_write USING 'Directly Appending' 'LOOP - ASSIGNING'
lv_rtime.
"CORRESPONDING
FREE lt_itab2.
GET RUN TIME FIELD lv_rtime.
lt_itab2 = CORRESPONDING #( lt_temp ).
PERFORM determine_write USING 'Directly Appending' 'CORRESPONDING'
lv_rtime.
"MOVE-CORRESPONDING
* FREE lt_itab2.
GET RUN TIME FIELD lv_rtime.
CLEAR lt_itab2.
MOVE-CORRESPONDING lt_temp TO lt_itab2.
PERFORM determine_write USING 'Directly Appending' 'MOVE-CORRESPONDING'
lv_rtime.
"VALUE FOR
FREE lt_itab.
GET RUN TIME FIELD lv_rtime.
lt_itab = VALUE #( FOR ls2 IN lt_temp
( sign = 'I'
option = 'EQ'
low = ls2-fieldname ) ).
PERFORM determine_write USING 'APPEND VALUE #' 'VALUE FOR - INTO'
lv_rtime.
FREE lt_itab.
GET RUN TIME FIELD lv_rtime.
lt_itab = VALUE #( FOR <lfs2> IN lt_temp
( sign = 'I'
option = 'EQ'
low = <lfs2>-fieldname ) ).
PERFORM determine_write USING 'APPEND VALUE #' 'VALUE FOR - ASSIGNING'
lv_rtime.
"LOOP VALUE
FREE lt_itab.
GET RUN TIME FIELD lv_rtime.
LOOP AT lt_temp INTO DATA(ls_temp2).
APPEND VALUE #( sign = 'I'
option = 'EQ'
low = ls_temp2-fieldname ) TO lt_itab.
ENDLOOP.
PERFORM determine_write USING 'APPEND VALUE #' 'LOOP VALUE with INTO'
lv_rtime.
FREE lt_itab.
GET RUN TIME FIELD lv_rtime.
LOOP AT lt_temp ASSIGNING FIELD-SYMBOL(<lfs_temp1>).
APPEND VALUE #( sign = 'I'
option = 'EQ'
low = <lfs_temp1>-fieldname ) TO lt_itab.
ENDLOOP.
PERFORM determine_write USING 'APPEND VALUE #' 'LOOP VALUE with ASSIGNING'
lv_rtime.
FREE lt_itab.
GET RUN TIME FIELD lv_rtime.
LOOP AT lt_temp REFERENCE INTO DATA(ld_temp1).
APPEND VALUE #( sign = 'I'
option = 'EQ'
low = ld_temp1->fieldname ) TO lt_itab.
ENDLOOP.
PERFORM determine_write USING 'APPEND VALUE #' 'LOOP VALUE with REFERENCE'
lv_rtime.
"VALUE FOR CORRESPONDING
FREE lt_itab.
GET RUN TIME FIELD lv_rtime.
lt_itab = VALUE #( FOR ls3 IN lt_temp
( VALUE #( BASE CORRESPONDING #( ls3
MAPPING low = fieldname )
sign = 'I'
option = 'EQ' ) ) ).
PERFORM determine_write USING 'APPEND CORRESPONDING #' 'VALUE FOR CORRESPONDING'
lv_rtime.
"LOOP CORRESPONDING
FREE lt_itab.
GET RUN TIME FIELD lv_rtime.
LOOP AT lt_temp ASSIGNING FIELD-SYMBOL(<lfs_temp2>).
ls_itab = CORRESPONDING #( <lfs_temp2>
MAPPING low = fieldname ).
ls_itab-sign = 'I'.
ls_itab-option = 'EQ'.
APPEND ls_itab TO lt_itab.
ENDLOOP.
PERFORM determine_write USING 'APPEND CORRESPONDING #' 'LOOP CORRESPONDING'
lv_rtime.
"CORRESPONDING
FREE lt_itab.
GET RUN TIME FIELD lv_rtime.
lt_itab = CORRESPONDING #( lt_temp
MAPPING low = fieldname ).
READ TABLE lt_itab INTO ls_itab INDEX 1.
ls_itab-sign = 'I'.
ls_itab-option = 'EQ'.
MODIFY lt_itab FROM ls_itab TRANSPORTING sign option WHERE sign IS INITIAL.
PERFORM determine_write USING 'APPEND CORRESPONDING #' 'CORRESPONDING & MODIFY'
lv_rtime.
"LOOP Using WA
FREE lt_itab.
GET RUN TIME FIELD lv_rtime.
LOOP AT lt_temp INTO ls_temp.
ls_itab-sign = 'I'.
ls_itab-option = 'EQ'.
ls_itab-low = ls_temp-fieldname.
APPEND ls_itab TO lt_itab.
ENDLOOP.
PERFORM determine_write USING 'LOOP 처리 방식 차이' 'LOOP Using WA'
lv_rtime.
"LOOP Using WA & Clear wa
FREE lt_itab.
GET RUN TIME FIELD lv_rtime.
LOOP AT lt_temp INTO ls_temp.
ls_itab-sign = 'I'.
ls_itab-option = 'EQ'.
ls_itab-low = ls_temp-fieldname.
APPEND ls_itab TO lt_itab.
CLEAR ls_itab.
ENDLOOP.
PERFORM determine_write USING 'LOOP 처리 방식 차이' 'LOOP Using WA & Clear wa'
lv_rtime.
"LOOP LOOP MOVE-CORRESPONDING
FREE lt_itab.
GET RUN TIME FIELD lv_rtime.
LOOP AT lt_temp INTO ls_temp.
MOVE-CORRESPONDING ls_temp TO ls_itab.
ls_itab-sign = 'I'.
ls_itab-option = 'EQ'.
ls_itab-low = ls_temp-fieldname.
APPEND ls_itab TO lt_itab.
CLEAR ls_itab.
ENDLOOP.
PERFORM determine_write USING 'LOOP 처리 방식 차이' 'LOOP MOVE-CORRESPONDING'
lv_rtime.
"LOOP
FREE lt_itab.
GET RUN TIME FIELD lv_rtime.
LOOP AT lt_temp INTO DATA(ls_temp9).
ls_itab-sign = 'I'.
ls_itab-option = 'EQ'.
ls_itab-low = ls_temp2-fieldname.
APPEND ls_itab TO lt_itab.
ENDLOOP.
PERFORM determine_write USING 'LOOP 처리 방식 차이' 'LOOP INTO DATA'
lv_rtime.
FREE lt_itab.
GET RUN TIME FIELD lv_rtime.
LOOP AT lt_temp ASSIGNING FIELD-SYMBOL(<lfs_temp9>).
ls_itab-sign = 'I'.
ls_itab-option = 'EQ'.
ls_itab-low = <lfs_temp9>-fieldname.
APPEND ls_itab TO lt_itab.
ENDLOOP.
PERFORM determine_write USING 'LOOP 처리 방식 차이' 'LOOP ASSIGNING'
lv_rtime.
FREE lt_itab.
GET RUN TIME FIELD lv_rtime.
LOOP AT lt_temp REFERENCE INTO DATA(ld_temp9).
ls_itab-sign = 'I'.
ls_itab-option = 'EQ'.
ls_itab-low = ld_temp9->fieldname.
APPEND ls_itab TO lt_itab.
ENDLOOP.
PERFORM determine_write USING 'LOOP 처리 방식 차이' 'LOOP REFERENCE'
lv_rtime.
"Result
ycl_salv_output=>display( lt_result ).
*&---------------------------------------------------------------------*
*& Form DETERMINE_WRITE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> P_
*& --> LV_SDATE
*& --> LV_STIME
*&---------------------------------------------------------------------*
FORM determine_write USING pv_category
pv_text
pv_rtime.
DATA: lv_rtime TYPE i,
lv_ftime TYPE i.
GET RUN TIME FIELD lv_rtime.
lv_ftime = lv_rtime - pv_rtime.
APPEND VALUE #( step = lines( lt_result ) + 1
category = pv_category
text = pv_text
rtime = lv_ftime
rtime_unit = MicroSecond ) TO lt_result.
* WRITE :/ pv_text,
* 30 ' : ', lv_ftime, 'MicroSecond'.
ENDFORM.
'ABAP > 개발Tip' 카테고리의 다른 글
[개발Tip] ALV 리포트의 백그라운드 실행 (0) | 2025.03.02 |
---|---|
[개발Tip] Internal Table 순차탐색과 Secondary Key 성능 비교 (0) | 2024.11.07 |
[개발Tip] ALV의 필드 정렬과 셀 정렬을 다르게 하고 싶을때 (0) | 2024.10.24 |
[개발Tip] ASCII 기준 문자열 자르기 (0) | 2024.10.24 |
[개발Tip] WebGUI에서 Excel 업로드(CL_FDT_XL_SPREADSHEET/ABAP2XLSX) (1) | 2023.12.07 |
댓글