Cod*_*erW 2 performance abap internal-tables
Suppose I have 2 internal tables:
TYPES:BEGIN OF LTY_FILE,
SOKEY TYPE CHAR5,
SOPONO TYPE CHAR15,
SOCONO TYPE CHAR15,
FLAG TYPE C,
END OF LTY_FILE.
data:IT_ARCHIVE TYPE TABLE OF LTY_FILE,
IT_SAP TYPE TABLE OF LTY_FILE.
it_archive = VALUE #(
( sokey = 'Key1' sopono = 'PO#12' socono = 'Three' flag = 'A' )
( sokey = 'Key2' sopono = 'PO#34' socono = 'Four' flag = 'B' ) ).
it_sap = VALUE #(
( sokey = 'Key1' sopono = 'PO#12' socono = 'Three' flag = 'A' ) ).
Run Code Online (Sandbox Code Playgroud)
IT_ARCHIVE:
| SOKEY | SOPONO | SOCONO | FLAG |
|---|---|---|---|
| Key1 | PO#12 | Three | A |
| Key2 | PO#34 | Four | B |
IT_SAP:
| SOKEY | SOPONO | SOCONO | FLAG |
|---|---|---|---|
| Key1 | PO#12 | Three | A |
Now I want the lines from IT_ARCHIVE which don't exist in IT_SAP, based on keys SOKEY, SOPONO and SOCONO, to be added to IT_SAP with FLAG = D:
| SOKEY | SOPONO | SOCONO | FLAG |
|---|---|---|---|
| Key2 | PO#34 | Four | B |
So, new IT_SAP should look like:
| SOKEY | SOPONO | SOCONO | FLAG |
|---|---|---|---|
| Key1 | PO#12 | Three | A |
| Key2 | PO#34 | Four | D |
Until now, I have tried following ways,but failed in ABAP 7.4, but as the data is quite huge (more than 400K in each run), I am looking for performance centric code to achieve this.
DATA(ls_wa) = it_sap[ 1 ]. " Temporary workarea for insertion.
CLEAR:ls_wa
LOOP AT IT_ARCHIVE ASSIGNING FIELD SYMBOL(<lfs_archive>).
IF NOT LINE_EXISTS( it_sap[ sokey = <lfs_Archive>-sokey
sopono = <lfs_Archive>-sopono
socono = <lfs_archive>-socono ] ).
ls_wa = <lfs_archive>.
ls_wa-flag = 'D'.
APPEND ls_wa to IT_SAP.
CLEAR:ls_wa.
ENDIF.
ENDLOOP.
Run Code Online (Sandbox Code Playgroud)
Second approach I tried:
data(LT_FINAL) = IT_SAP[].
REFRESH:LT_FINAL[].
lt_final = VALUE #( FOR ls_ar IN IT_ARCHIVE
FOR ls_sap IN IT_SAP WHERE ( sokey <> <lfs_Archive>-sokey
sopono <> <lfs_Archive>-sopono
socono <> <lfs_archive>-socono )
(
"Explicitly mentioning all fields as have to change FLAG value
sokey = ls_Ar-sokey
sopono = ls_ar-sopono
socono = ls_ar-socono
flag = 'D'
) ).
Run Code Online (Sandbox Code Playgroud)
第一种方法需要太多时间,因为数据量很大。令我惊讶的是,第二种方法给我的结果与第一种方法不同。
在 ABAP 7.4+ 中有没有更好的方法来实现这一点?
您的主要问题是关于性能。有关信息,堆栈溢出中还有其他关于性能和内部表的类似问题/答案。
在您的情况下,您使用“标准”表类型 ( DATA ... TYPE TABLE OF ...),因此每次查找 ( line_exists) 将查看内部表的所有行,直到找到一行。与其一遍又一遍地查看所有行,最好将内表排序一次,每次查找都会快很多;这很容易理解为什么:如果你,人类,看看字典(书)中的一个词,希望这些词被排序,你会很快找到这个词(前提是你知道字母 A、B、C 等的顺序) .; 电脑也是一样。
内表排序有两种方式:
SORT。此选项更易于理解,但在可能的情况下强烈不建议使用。要在排序和散列(即隐式排序)之间进行选择,您必须简单地知道是否可能有两行具有完全相同的键。
在您的情况下,只需执行以下声明即可显着提高您当前(工作)算法的性能:
TYPES:BEGIN OF lty_file,
sokey TYPE char5,
sopono TYPE char15,
socono TYPE char15,
flag TYPE c,
END OF lty_file.
TYPES:lty_file_tab TYPE SORTED TABLE OF lty_file WITH NON-UNIQUE KEY sokey sopono socono.
DATA:it_archive TYPE lty_file_tab,
it_sap TYPE lty_file_tab.
Run Code Online (Sandbox Code Playgroud)
您还可以通过使用FILTER我认为在内核中运行更多的内置运算符来改进您的算法(有关FILTER其他问题的答案的更多信息)。
例如:
it_sap = VALUE #(
BASE it_sap
( LINES OF VALUE #( FOR <line> IN
FILTER #( it_archive EXCEPT IN it_sap
WHERE sokey = sokey
AND sopono = sopono
AND socono = socono )
( VALUE #( BASE <line> flag = 'D' ) ) ) ) ).
ASSERT it_sap = VALUE lty_file_tab(
( sokey = 'Key1' sopono = 'PO#12' socono = 'Three' flag = 'A' )
( sokey = 'Key2' sopono = 'PO#34' socono = 'Four' flag = 'D' ) ).
Run Code Online (Sandbox Code Playgroud)
(注意:我ASSERT在这里使用只是为了证明内部表具有指示值;否则会停止程序/引发运行时错误)
| 归档时间: |
|
| 查看次数: |
181 次 |
| 最近记录: |