ABAP tips Checking existence within an internal table

作者:郑德鼎 约 3 分钟阅读 更新日期:2024-02-22 2 年前更新 标签:ABAP, 开发
目录

Mike Pokraka

Posted onJune 23, 2018 2 minute read

ABAP tips: Checking existence within an internal table

FollowRSS feedLike

42 Likes 34,072 Views 30 Comments

I got a blog-worthy surprise when I did a quick performance test on two different ways to use the new-ish (7.4) table expressions to perform a search on an internal table.

My scenario involved internal table searches where the values would be missing a lot of the time. The unexpected result was that when a row can’t be found, using table expressions with exceptions is ten times slower on average than all other lookup methods, including the good ol’ fashioned READ TABLE with SY-SUBRC.

Quick primer for those still getting accustomed to 7.4 ABAP (feel free to skip to the results):

With table expressions, finding an entry in a table is really neat. I have a table that includes a field “ID”. So the following READ TABLE can be rewritten using a table expression (the bit in square brackets):

READ TABLE itab INTO row WITH KEY id = find_id.

"Equivalent to

row = itab[ id = find_id ].

If the matching entry cannot be found, you need to catch the exception

TRY.
row = itab[ id = find_id ].
CATCH cx_sy_itab_line_not_found.

...

ENDTRY.

Another alternative is to use a VALUE constructor expression where you can add the keyword OPTIONAL (or DEFAULT) to just initialize any non-found values.

row = VALUE #( itab[ id = find_id ] OPTIONAL ).
IF row IS INITIAL.

...

This particular usage of VALUE may seem a little awkward. I mean, why use x = VALUE #( y ) when you can just write x = y? The VALUE constructor’s sole purpose here is the OPTIONAL bit that lets us do away with the exception.

As I was working on a performance-sensitive component, I tested it to see what performs best.

Results

For completeness, and additionally with suggestions by Jacques Nomssi, Quynh Doan Manh and Uwe Fetzer in the comments, I also added a couple of other ways to look for an entry in a table:

The trusty READ TABLE  … WITH KEY, with and without TRANSPORTING NO FIELDS

line_exists( )

ASSIGN itab[ … ]  – which (bizarrely) sets SY-SUBRC instead of producing an exception

REF #( ) instead of VALUE #( ).

I tested a million failed lookups on a 7.50 HANA system. Here are the results in microseconds:

line_exists( ) : 610,758

READ TABLE ... TRANSPORTING NO FIELDS : 671,368
READ TABLE : 671,115

ASSIGN itab[ ... ] : 707,929

REF #( itab[ ... ] OPTIONAL ) : 888,562

VALUE #( itabl[ ... ] OPTIONAL ) : 961,803

TRY ... itab[ ... ] CATCH : 6,325,265

I did not expect the last one at all.

So the take-away here for me is that a TRY-CATCH may be easier to read, but should not be used in performance-sensitive code unless you expect the values to be found most of the time. I’m happy to sacrifice a little performance for readability, but this is a significant impact.

I suspect that this applies to CATCH blocks in general, but that’s another analysis for another day.

For comparison, I also re-ran the same but this time with a lookup value that did exist. Two things happened:

the exception was no longer an influence (to be expected)

line_exists( ) became a poor choice in my scenario, because we need to double up the the search in order to also read the record:

IF line_exists( itab[ id = find_id ] ).
row = itab[ id = find_id ].

To summarise

If you don’t need the data, line_exists( ) is fastest.

If performance is number 1 priority and you need the data, READ TABLE is fastest.

For compact and/or readable code, use table expressions.

(Yes, I know, ‘new’ ABAP can be used to make code either more readable or more cryptic, but that’s another discussion)

TRY-CATCH with table expressions can be a useful way to structure your code (e.g. to use a single catch handler for multiple expressions), but be mindful of the expected failure rate and performance-criticality of the component. If we’re talking anything less than thousands in a short space of time then you can safely ignore the impact.

Update

After several comments and suggestions, I uploaded my test program to GitHub at abap_itab_perf

It was just a quick-n-dirty originally for comparing just two options and just grew as a copy/paste of alternatives. Feel free to play with it or even send any updates back via GitHub.

郑德鼎

关于作者:郑德鼎

企业信息化与 SAP 技术顾问,长期专注 SAP ABAP、FI/CO、MM、SD 等模块的技术分享与实战经验总结。查看更多介绍

来源说明:本文内容由「ABAP tips Checking existence within an internal table.docx」整理生成,仅用于内部技术分享与学习交流。