ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

双LOOP循环的性能优化

2021-12-30 21:00:16  阅读:188  来源: 互联网

标签:gt wa ty col2 col1 lv 循环 优化 LOOP


平时开发过程中遇到一些复杂的逻辑可能避免不了要用双LOOP循环的场景,这种情况下程序的性能是个很大的问题。数据量大一点的程序动辄3-5分钟,更有甚者直接跑到time out。

最近我学习整理了几种双LOOP循环性能优化的方法,在这里记录并分享一下。

首先,我们写一段没有经过优化的双LOOP循环来看看效果。

REPORT test_loop.

TYPES:BEGIN OF ty_a,
        col1(10),
        col2(10),
      END OF ty_a,
      BEGIN OF ty_b,
        col1(10),
        col3(10),
      END OF ty_b,
      BEGIN OF ty_c,
        col1(10),
        col2(10),
        col3(10),
      END OF ty_c.

DATA:wa_a TYPE ty_a,
     wa_b TYPE ty_b,
     wa_c TYPE ty_c,
     gt_a TYPE TABLE OF ty_a,
     gt_b TYPE TABLE OF ty_b,
     gt_c TYPE TABLE OF ty_c.

START-OF-SELECTION.

PERFORM frm_getdata.
PERFORM frm_loop.

FORM frm_getdata.
  DATA lv_line(5) TYPE n.

  DO 5000 TIMES.
    lv_line = sy-index.

    CLEAR wa_a.
    wa_a-col1 = 'col1'&& lv_line.
    wa_a-col2 = 'col2'&& lv_line.
    APPEND wa_a TO gt_a.

    CLEAR wa_b.
    wa_b-col1 = 'col1'&& lv_line.
    wa_b-col3 = 'col3'&& lv_line.
    APPEND wa_b TO gt_b.
  ENDDO.
ENDFORM.

FORM frm_loop.
  DATA lv_t TYPE i.
  GET RUN TIME FIELD DATA(time1).
  LOOP AT gt_a INTO wa_a.
    LOOP AT gt_b INTO wa_b WHERE col1 = wa_a-col1.
      wa_c-col1 = wa_a-col1.
      wa_c-col2 = wa_a-col2.
      wa_c-col3 = wa_b-col3.
      APPEND wa_c TO gt_c.
      CLEAR wa_c.
    ENDLOOP.
  ENDLOOP.
  GET RUN TIME FIELD DATA(time2).
  lv_t = time2 - time1.
  WRITE:/'未经优化,5000条数据执行时间:',lv_t,'微秒'.
ENDFORM.

执行结果:

优化方法1:排序表优化

定义一个排序表并赋值给它,使用排序表进行LOOP循环。

 

FORM frm_loop_sort.
  GET RUN TIME FIELD DATA(time1).
  DATA:gt_b_sort TYPE SORTED TABLE OF ty_b WITH NON-UNIQUE KEY col1.
  SORT gt_b BY col1.
  gt_b_sort[] = gt_b[].
  LOOP AT gt_a INTO wa_a.
    LOOP AT gt_b_sort INTO wa_b WHERE col1 = wa_a-col1.
      wa_c-col1 = wa_a-col1.
      wa_c-col2 = wa_a-col2.
      wa_c-col3 = wa_b-col3.
      APPEND wa_c TO gt_c.
      CLEAR wa_c.
    ENDLOOP.
  ENDLOOP.
  REFRESH gt_c.
  GET RUN TIME FIELD DATA(time2).
  lv_t = time2 - time1.
  WRITE:/'经排序表优化,5000条数据执行时间:',lv_t,'微秒'.
ENDFORM.

执行结果:

 

优化方法2:内表排序INDEX优化

对标准表进行排序并使用INDEX方式进行优化,此方法使用有局限性,要求gt_a-col1不能重复,一旦重复,结果就不对了。

FORM frm_sort_index.
  GET RUN TIME FIELD DATA(time1).
  DATA:i TYPE i.
  SORT:gt_a BY col1,
       gt_b BY col1.
  i = 1.
  LOOP AT gt_a INTO wa_a.
    LOOP AT gt_b INTO wa_b FROM i.
      IF wa_a-col1 <> wa_b-col1.
        i = sy-tabix.
        EXIT.
      ENDIF.
      wa_c-col1 = wa_a-col1.
      wa_c-col2 = wa_a-col2.
      wa_c-col3 = wa_b-col3.
      APPEND wa_c TO gt_c.
      CLEAR wa_c.
    ENDLOOP.
  ENDLOOP.
  REFRESH gt_c.
  GET RUN TIME FIELD DATA(time2).
  lv_t = time2 - time1.
  WRITE:/'经内表排序INDEX优化,5000条数据执行时间:',lv_t,'微秒'.
ENDFORM.

执行结果:

暂时先写这两种优化方法,其它方法后面再继续加。 

 

完整代码:

REPORT test_loop.

TYPES:BEGIN OF ty_a,
        col1(10),
        col2(10),
      END OF ty_a,
      BEGIN OF ty_b,
        col1(10),
        col3(10),
      END OF ty_b,
      BEGIN OF ty_c,
        col1(10),
        col2(10),
        col3(10),
      END OF ty_c.

DATA:wa_a TYPE ty_a,
     wa_b TYPE ty_b,
     wa_c TYPE ty_c,
     gt_a TYPE TABLE OF ty_a,
     gt_b TYPE TABLE OF ty_b,
     gt_c TYPE TABLE OF ty_c,
     lv_t TYPE i.

START-OF-SELECTION.

  PERFORM frm_getdata.
  PERFORM frm_loop.
  PERFORM frm_loop_sort.
  PERFORM frm_sort_index.
  PERFORM frm_hs_group.


FORM frm_getdata.
  DATA lv_line(5) TYPE n.

  DO 5000 TIMES.
    lv_line = sy-index.

    CLEAR wa_a.
    wa_a-col1 = 'col1'&& lv_line.
    wa_a-col2 = 'col2'&& lv_line.
    APPEND wa_a TO gt_a.

    CLEAR wa_b.
    wa_b-col1 = wa_a-col1.
    wa_b-col3 = 'col3'&& lv_line.
    APPEND wa_b TO gt_b.
  ENDDO.
ENDFORM.

FORM frm_loop.
  GET RUN TIME FIELD DATA(time1).
  LOOP AT gt_a INTO wa_a.
    LOOP AT gt_b INTO wa_b WHERE col1 = wa_a-col1.
      wa_c-col1 = wa_a-col1.
      wa_c-col2 = wa_a-col2.
      wa_c-col3 = wa_b-col3.
      APPEND wa_c TO gt_c.
      CLEAR wa_c.
    ENDLOOP.
  ENDLOOP.
  REFRESH gt_c.
  GET RUN TIME FIELD DATA(time2).
  lv_t = time2 - time1.
  WRITE:/'未经优化,5000条数据执行时间:',lv_t,'微秒'.
ENDFORM.

FORM frm_loop_sort.
  GET RUN TIME FIELD DATA(time1).
  DATA:gt_b_sort TYPE SORTED TABLE OF ty_b WITH NON-UNIQUE KEY col1.
  SORT gt_b BY col1.
  gt_b_sort[] = gt_b[].
  LOOP AT gt_a INTO wa_a.
    LOOP AT gt_b_sort INTO wa_b WHERE col1 = wa_a-col1.
      wa_c-col1 = wa_a-col1.
      wa_c-col2 = wa_a-col2.
      wa_c-col3 = wa_b-col3.
      APPEND wa_c TO gt_c.
      CLEAR wa_c.
    ENDLOOP.
  ENDLOOP.
  REFRESH gt_c.
  GET RUN TIME FIELD DATA(time2).
  lv_t = time2 - time1.
  WRITE:/'经排序表优化,5000条数据执行时间:',lv_t,'微秒'.
ENDFORM.

FORM frm_sort_index.
  GET RUN TIME FIELD DATA(time1).
  SORT:gt_a BY col1,
       gt_b BY col1.
  LOOP AT gt_a INTO wa_a.
    LOOP AT gt_b INTO wa_b FROM sy-tabix.
      IF wa_a-col1 <> wa_b-col1.
        EXIT.
      ENDIF.
      wa_c-col1 = wa_a-col1.
      wa_c-col2 = wa_a-col2.
      wa_c-col3 = wa_b-col3.
      APPEND wa_c TO gt_c.
      CLEAR wa_c.
    ENDLOOP.
  ENDLOOP.
  REFRESH gt_c.
  GET RUN TIME FIELD DATA(time2).
  lv_t = time2 - time1.
  WRITE:/'经内表排序INDEX优化,5000条数据执行时间:',lv_t,'微秒'.
ENDFORM.

 

 

标签:gt,wa,ty,col2,col1,lv,循环,优化,LOOP
来源: https://blog.csdn.net/anji0207/article/details/122245166

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有