ABAP Performance Series - Loop nested loop

Oct. 22, 2019 | 180 views

Loop nested loop

Trong quá trình phát triển ứng dụng không thể tránh khỏi việc sử dụng loop trong loop. Tuy nhiên trong sap abap loop trong loop sẽ rất chậm. Có một số cách cải thiện loop trong loop.

Giả sử cần xử lý dữ liệu của BSEG từ BKPF

LOOP AT LT_BKPF INTO LS_BKPF.
  LOOP AT LT_BSEG INTO LS_BSEG.
    IF LS_BSEG-BUKRS = LS_BKPF-BUKRS
      AND LS_BSEG-BELNR = LS_BKPF-BELNR
      AND LS_BSEG-GJAHR = LS_BKPF-GJAHR.
*   Code Process Logic Details...
    ENDIF.
  ENDLOOP.
ENDLOOP.

Với vòng loop xử lý trên thì loop lt_bseg sẽ chạy toàn bộ. Để cải thiện hơn chúng ta có thể sử dụng loop where.

LOOP AT LT_BKPF INTO LS_BKPF.
  LOOP AT LT_BSEG INTO LS_BSEG
    WHERE BUKRS = LS_BKPF-BUKRS
      AND BELNR = LS_BKPF-BELNR
      AND GJAHR = LS_BKPF-GJAHR.
*   Code Process Logic Details...
  ENDLOOP.
ENDLOOP.

Tuy nhiên performance loop where vẫn không được cải thiện nhiều lắm nó mới loại bỏ các phần loop dữ liệu không cần thiết. Trong SAP ABAP còn cho phép loop tại vị trí con trỏ nào đó trong loop đó là loop from <index>.

Để sử dụng loop from <index> thì dữ liệu trong internal table phải được sorted. Khi sử dụng loop from <index> thì không thể sử dụng mệnh đề where trong loop.

SORT LT_BKPF BY BUKRS GJAHR BELNR.
SORT LT_BSEG BY BUKRS GJAHR BELNR.
LOOP AT LT_BKPF INTO LS_BKPF.
  CLEAR: LW_INDEX.
  READ TABLE LT_BSEG TRANSPORTING NO FIELDS
  WITH KEY BUKRS = LS_BKPF-BUKRS
           BELNR = LS_BKPF-BELNR
           GJAHR = LS_BKPF-GJAHR.
  CHECK SY-SUBRC IS INITIAL.
  LW_INDEX = SY-TABIX.
  LOOP AT LT_BSEG INTO LS_BSEG FROM LW_INDEX.
    AT END OF BELNR.
      EXIT.
    ENDAT.
*   Code Process Logic Details...
  ENDLOOP.
ENDLOOP.

Ngoài ra chúng ta có thể không sử dụng read để tìm ra index bắt đầu, nếu cả loop cha và loop con được sort.

*--------------------------------------------------------------------*
*& Loop pararell cursor without read
*--------------------------------------------------------------------*
" Not user Read
LW_INDEX = 1.
GET RUN TIME FIELD LW_START.
LOOP AT LT_BKPF INTO LS_BKPF.
  LOOP AT LT_BSEG INTO LS_BSEG FROM LW_INDEX.
    IF NOT ( LS_BSEG-BUKRS = LS_BKPF-BUKRS
         AND LS_BSEG-BELNR = LS_BKPF-BELNR
         AND LS_BSEG-GJAHR = LS_BKPF-GJAHR ).
*   Code Process Logic Details...
      LW_INDEX = SY-TABIX.
      EXIT.
    ENDIF.
*   Code Process Logic Details...
  ENDLOOP.
ENDLOOP.
GET RUN TIME FIELD LW_END.
LW_TIME = LW_END - LW_START.
WRITE: / 'Loop nested loop parallel cursor without read: ', LW_TIME.

Ví dụ

Code chương trình sample