😎 SAP ABAP 嵌套 LOOP 优化实例 & 解析

首页 / 💰笔记 / 正文

SAP ABAP 嵌套 LOOP 优化实例 & 解析

前言

代码需求:实现相同 HEAD 打印(如下实例为打印所有和选中行匹配相同的 MATNR 的数据)

优化前

最笨最不考虑性能的方案:无脑双层嵌套,然后 比对 MATNR 即可,示例如下:

LOOP AT gt_data_sel ASSIGNING FIELD-SYMBOL(<fs_sel>). " gt_data_sel 为已经对选中行数据进行唯一性筛选后的数据
    LOOP AT gt_data ASSIGNING FIELD-SYMBOL(<fs_data>).
        IF <fs_data>-matnr EQ <fs_sel>-matnr.
            APPEND <fs_data> TO gt_output.  " MATNR 一致的,放到 gt_output 中(归属于同一 HEAD)
        ENDIF.
    ENDLOOP.
​
    " 然后后续代码将同一 HEAD 的数据 gt_output 进行打印即可...
ENDLOOP.
由于文章为同时推送,代码排版若有问题,阅读下图代码即可:

SAP-Nested-LOOP-STAIN-01.png


优化后

SORT + LOOP + LOOP FROM index 的优化方案,具体逻辑看注释即可
" 首先对 数据总表 和 选中行数据表 按照 MATNR 排序
" 这里的排序有两点意义:
    " 1. 后续 READ TABLE 时用到了二分法,所以要排序
    " 2. 后续 LOOP FROM index 时 排序就有了意义,具体意义解析参见后续代码注释 PS 部分
SORT: gt_data BY matnr,
      gt_data_sel BY matnr.
​
LOOP AT gt_data_sel ASSIGNING FIELD-SYMBOL(<fs_sel>).
    READ TABLE gt_data TRANSPORTING NO FIELDS WITH KEY matnr = <fs_sel>-matnr BINARY SEARCH.
    IF sy-subrc = 0.
        lv_tabix = sy-tabix. " 获取到第一条相同 MATNR 数据的索引位置
    ENDIF.
​
    " 这里我们每次 LOOP gt_data 都是从 获取到第一条相同 MATNR 数据的位置开始读取
    " 这样做的意义:
        " 1. 假设 gt_data 数据量为 10 万
        " 2. 我们获取到的这个 MATNR 的索引位置为第 30001 位
        " 3. 那么我们每次循环都是从第 30001 位开始读,每次循环省去了「前面 30000 条数据读取 + 进入循环匹配 MATNR」的时间
    " PS: 这里每次从 30001 位开始读,「能够读到其后面的 MATNR 为按序排列」的前提条件就是我们前面已经对 gt_data 做了以 MATNR 为 key 的排序
    LOOP AT gt_data FROM lv_tabix ASSIGNING FIELD-SYMBOL(<fs_data>).
        IF <fs_data>-matnr <> <fs_sel>-matnr.
            EXIT.
        ENDIF.
​
        APPEND <fs_data> TO gt_output. " MATNR 一致的,放到 gt_output 中(归属于同一 HEAD)
    ENDLOOP.
ENDLOOP.
由于文章为同时推送,代码排版若有问题,阅读下图代码即可:

SAP-Nested-LOOP-STAIN-02.png


总结

实际感受一下能差多少条数据量呢,我们可以粗略估算一下,以下计算可能会有疏忽,仅作参考~

前提假设:

  • gt_data 数据量为 10 万
  • gt_data_sel 仅选中了 1 条数据
  • 读到 MATNR 索引位置为 第 30001
  • 同一 MATNR 的数据有 3

双层嵌套:1 * 100,000 = 100,000 -> 10 万次

优化后:1 + (粗略猜一下,二分大概 10 次左右) + 1 + 2 + 3 = 17 -> 17 次

您阅读这篇文章共花了:
打赏
评论区
头像
文章目录