In the first two articles of this series we had a look at how to best read data from database tables. The Code Inspector checks whether the database access has a WHERE clause that will be able to make use of a database index, or if an access to a buffered table will implicitly bypass the SAP table buffers.
Articles of this series:
Now that you have read data from the database to the application server efficiently, it is essential that you streamline the way in which you deal with the data inside your program.
One big threat to the scalability of a program is large internal tables that are accessed sequentially (see Runtimes of Reads and Loops on Internal Tables). Sequential access means, that each individual entry of the internal table is accessed by the ABAP runtime in a single step loop - either until a certain key value is found, or until the end of the internal table has been reached. This implies that a sequential access can be fast - but only if the entry searched for is at the beginning of the search area. However, on average, half of the internal table has to be stepped through to find one entry with sequential search.
In contrast, optimized accesses are non-sequential and apply indexes, binary or hashed key searches. So, while the sequential access scales linearly with the amount of processed data, optimized accesses scale logarithmic or even better (i.e. constant access time independent of amount of data).
Moreover: once you start nesting internal tables in your program, for example a statement READ TABLE itab2 inside a LOOP AT itab1 ... ENDLOOP, you can get caught out by quadratic run time behavior. This will happen if the size of the two internal tables depends linearly on the amount of data processed in your program, and if the access to the inner table is not optimized.
This article presents a Code Inspector check that detects sequential (or 'non-optimized') accesses to internal tables.
In ABAP, internal tables can be specified according to the following table categories:
Additionally there are the generic table categories ANY TABLE and INDEX TABLE.
SORTED and HASHED tables have a table key that speeds up the table access if the key is fully specified. In the case of the SORTED table, the access can also be optimized if just the leading part of the key is specified in the READ or LOOP statement.
Fast accesses to STANDARD and SORTED tables are possible by using the table index, that is, the position of an entry in the table.
A fast access to a STANDARD table can also be achieved by using the option BINARY SEARCH in the READ accesses. To return correct results, the table must be sorted appropriately.
The following accesses to internal tables may result in a sequential search:
The check ‘Low Performance Operations on Internal Tables' has four attributes corresponding to the different table types that can be checked: STANDARD, SORTED, HASHED, and GENERICALLY typed tables.
If you define an IMPORTING parameter for a method as type ‘ANY TABLE' (that is, generically typed), the check tool will not know which non-generic table type this will be at runtime. It thus assumes that it will be a STANDARD table and accesses to the table are checked accordingly.
Note that in the global check variant ‘DEFAULT' of the Code Inspector the option to check STANDARD tables is normally de-selected.
The check itself is based on the ABAP compiler (class CL_ABAP_COMPILER) and its services. The compiler provides information like the type of an internal table that cannot be extracted easily by doing a simple source code scan. Here, the information as to whether the access to an internal table can be optimized or not is provided directly to the check framework.
The check detects non-optimized accesses to internal tables with the following statements (see above):
In the ‘Remarks' section below you will find some additional internal table statements that may be slow, but that will not give you a message with this check.
The possible Code Inspector messages for this check are:
Message | Default priority |
Sequential Read Access for a Standard Table | Information |
Possible Sequential Read Access for a Sorted Table | Warning |
Possible Sequential Read Access for a Hashed Table | Warning |
Possible Sequential Read Access for a Generically Typed Table | Warning |
Possible sequential access during deletion from a table | Warning |
The last message is only relevant with Release SAP NetWeaver 7.1 and higher. It comes into play when secondary table keys are defined for an internal table. Here, the deletion of entries in a STANDARD table via a SORTED or HASHED secondary key can lead to linear runtime behavior.
The static check tool has no clue about how many entries an internal table will have at runtime. Therefore, not all check messages will have the same relevance for the performance of the program execution.
Now, also you as the developer are unlikely to know exactly how many entries an internal table will have in a productively used customer system. To make things easy we propose that you only distinguish between ‘small' internal tables with a maximum of 20-30 entries on the one side, and ‘large' tables on the other side. All frequently executed accesses to large internal tables should be optimized, that is, use an index, or use a table key, or do a BINARY SEARCH. In many cases, a SORTED table will do the job (* see comment at end).
This is how you should advance in detail if there is a sequential access to an internal table:
There are further potentially slow operations on internal tables that are not reported by the check, but that can be observed in performance measurements:
(*) We do not discuss here cases were you need alternative access paths to large internal tables. The situation for such a scenario will improve in future with the new secondary table keys, but is rather complex for older releases.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
6 | |
5 | |
3 | |
3 | |
2 | |
2 | |
2 | |
2 | |
1 | |
1 |