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.
由于文章为同时推送,代码排版若有问题,阅读下图代码即可:
优化后
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.
由于文章为同时推送,代码排版若有问题,阅读下图代码即可:
总结
实际感受一下能差多少条数据量呢,我们可以粗略估算一下,以下计算可能会有疏忽,仅作参考~
前提假设:
gt_data
数据量为10 万
gt_data_sel
仅选中了1
条数据- 读到 MATNR 索引位置为 第
30001
位 - 同一 MATNR 的数据有
3
条
双层嵌套:1 * 100,000 = 100,000 -> 10 万次
优化后:1 + (粗略猜一下,二分大概 10 次左右) + 1 + 2 + 3 = 17 -> 17 次