ABAP 性能优化 (★★★)
#performance #internal-tables #abap-basics
内表类型选择
| 访问模式 |
最佳表类型 |
访问速度 |
| 按键单条记录查找 |
哈希表 |
O(1) 常数 |
| 按键范围顺序读取 |
排序表 |
O(log n) 二分 |
| 需要索引访问 |
排序表或标准表 |
O(1) 按索引 |
| 排序 / 重新排序 |
标准表 |
灵活排序 |
| 批量插入 / 追加 |
标准表 |
高效追加 |
避免循环中的复制
ASSIGNING / REFERENCE INTO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| " 不好:每次迭代都复制数据 LOOP AT lt_data INTO ls_data. ls_data-processed = abap_true. MODIFY lt_data FROM ls_data. ENDLOOP.
" 好:无复制,直接修改 LOOP AT lt_data ASSIGNING FIELD-SYMBOL(<ls_data>). <ls_data>-processed = abap_true. " 直接写入,不需要 MODIFY ENDLOOP.
" 好:引用(供后续使用) LOOP AT lt_data REFERENCE INTO lr_data. lr_data->*-processed = abap_true. ENDLOOP.
|
| 方法 |
复制? |
修改方式 |
适用场景 |
INTO wa |
是(复制) |
需要 MODIFY |
简单读取 |
ASSIGNING <fs> |
否 |
通过字段符号直接 |
原地修改 |
REFERENCE INTO dref |
否 |
通过 dref->* |
后续需要引用 |
字符串性能
| 反模式 |
更好的方法 |
| 循环中的连接 |
构建内表,然后 CONCATENATE LINES OF |
重复 CONCATENATE |
字符串模板(|...{expr}...|) |
SHIFT + CONCATENATE |
shift_left()、shift_right() 函数 |
1 2 3 4 5 6 7 8 9 10 11 12 13
| " 不好:循环中的连接 LOOP AT lt_names INTO ls_name. CONCATENATE lv_result ls_name-name INTO lv_result SEPARATED BY space. ENDLOOP.
" 好:表连接 LOOP AT lt_names INTO ls_name. APPEND ls_name-name TO lt_parts. ENDLOOP. lv_result = concat_lines_of( table = lt_parts sep = ` ` ).
" 好:字符串模板 lv_text = |Flight { lv_carrid }-{ lv_connid } on { lv_date DATE = USER }|.
|
类型转换开销
| 情况 |
影响 |
解决方案 |
| 比较不同类型 |
每行隐式转换 |
使用相同类型 |
将 p 赋值给 i |
运行时转换 |
声明时匹配类型 |
READ TABLE ... WITH KEY 类型不匹配 |
每次比较都转换 |
使用类型化的键 |
表键选择指南
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 标准表: - 使用场景:顺序处理、频繁排序、小表 - 键访问:线性 O(n) - 索引访问:是 - BINARY SEARCH:SORT 后可用
排序表: - 使用场景:部分顺序读取,同时需要键和索引 - 键访问:二分 O(log n) - 索引访问:是 - 次键:可用
哈希表: - 使用场景:按唯一键单条记录查找 - 键访问:哈希 O(1) - 索引访问:否 - 最适合:大型查找表
|
内存考虑
| 方面 |
详情 |
INITIAL SIZE n |
预分配内存;已知大小时使用以避免重新分配 |
FREE itab |
释放整个表内存(头部 + 表体) |
REFRESH itab |
清除表体但可能保留头部内存 |
CLEAR itab |
对内表等同于 REFRESH |
| 深层表 |
包含字符串/表的表使用更多内存;完成后 FREE |
1 2 3 4 5 6
| " 为已知大小预分配 DATA: lt_flights TYPE STANDARD TABLE OF sflight WITH INITIAL SIZE 1000.
" 完成后释放内存 FREE: lt_large_table, lt_temp_table.
|
性能汇总表
| 领域 |
反模式 |
最佳实践 |
| 表访问 |
标准表 + 线性搜索 |
哈希表(键)或排序表(范围) |
| 循环修改 |
INTO wa + MODIFY |
ASSIGNING <fs> |
| 字符串构建 |
循环连接 |
字符串模板、表连接 |
| 类型匹配 |
比较中混合类型 |
相同数据类型 |
| 内存 |
无 INITIAL SIZE,无 FREE |
预分配,完成后释放 |
考试/测试模式
| 关键词 / 短语 |
答案 |
| “单条记录查找的最佳表类型” |
哈希表 (O(1)) |
| “ASSIGNING 在 LOOP 中的优势” |
无行数据复制;直接修改 |
| “标准表使用 BINARY SEARCH” |
需要先按相同键 SORT |
| “字符串构建最佳实践” |
字符串模板或 concat_lines_of() |
| “INITIAL SIZE 用途” |
预分配内存避免重新分配 |
| “FREE vs REFRESH” |
FREE 释放所有内存;REFRESH 清除表体 |
| “类型转换开销” |
比较操作数使用相同类型 |
| “哈希表限制” |
无索引访问(READ … INDEX、LOOP … FROM/TO) |
相关笔记
- 数据库性能 - SQL 优化
- 内表类型 - 详细表类型比较
- 特殊表技术 - 次键、BINARY SEARCH
- 常见错误与规范 - 常见错误
- [[_posts/SAP_MM/SCM500_采购流程/00-仪表盘/学习地图]] - 学习地图