You are on page 1of 10

TIPS & TRICKS

NO YES

Select using an aggregate function


DATA: MAX_MSGNR type t100-msgnr.
DATA: MAX_MSGNR type t100-msgnr. SELECT MAX( MSGNR ) FROM T100 INTO max_msgnr
MAX_MSGNR = '000'. WHERE SPRSL = 'D' AND
SELECT * FROM T100 INTO T100_WA ARBGB = '00'.
WHERE SPRSL = 'D' AND
ARBGB = '00'.
CHECK: T100_WA-MSGNR > MAX_MSGNR.
MAX_MSGNR = T100_WA-MSGNR.
ENDSELECT.

Select ... Up To 1 Rows


SELECT * FROM SBOOK INTO SBOOK_WA SELECT * FROM SBOOK INTO SBOOK_WA
WHERE CARRID = 'LH'. UP TO 1 ROWS
EXIT. WHERE CARRID = 'LH'.
ENDSELECT. ENDSELECT.
If you are interested if there exists at least one row of a
database table or view with a certain condition, use the Select
... Up To 1 Rows statement instead of a Select-Endselect-loop
with an Exit.
If all primary key fields are supplied in the Where conditions you
can even use Select Single.
Select Single requires one communication with the database
system, whereas Select-Endselect needs two.
Single-line Updates Column Update
SELECT * FROM SFLIGHT INTO SFLIGHT_WA.
SFLIGHT_WA-SEATSOCC = UPDATE SFLIGHT
SFLIGHT_WA-SEATSOCC - 1. SET SEATSOCC = SEATSOCC - 1.
UPDATE SFLIGHT FROM SFLIGHT_WA.
ENDSELECT.

Whenever possible, use column updates instead of single-row


updates to update your database tables.
Network load is considerably less.
Select without index support Select with primary index support
SELECT * FROM SBOOK CLIENT SPECIFIED INTO SELECT * FROM SBOOK CLIENT SPECIFIED INTO
SBOOK_WA SBOOK_WA
WHERE CARRID = 'LH' WHERE MANDT IN ( SELECT MANDT FROM T000 )
AND CONNID = '0400'. AND CARRID = 'LH'
ENDSELECT. AND CONNID = '0400'.
For all frequently used Select statements, try to use an index. ENDSELECT.
You always use an index if you specify (a generic part of) the
index fields concatenated with logical Ands in the Select
statement's Where clause. Note that complex Where clauses
are poison for the statement optimizer in any database system.
Select without buffer support Select with buffer support
SELECT SINGLE * FROM T100 INTO T100_WA SELECT SINGLE * FROM T100 INTO T100_WA
BYPASSING BUFFER WHERE SPRSL = 'D'
WHERE SPRSL = 'D' AND ARBGB = '00'
AND ARBGB = '00' AND MSGNR = '999'.
AND MSGNR = '999'.
For all frequently used, read-only tables, try to use SAP
buffering. Network load is considerably less.
Select + Append statement Select Into Table
DATA T006_WA TYPE T006. SELECT * FROM T006 INTO TABLE X006.
CLEAR X006.
SELECT * FROM T006 INTO T006_WA.
It is always faster to use the Into Table version of a Select
APPEND T006_WA TO X006. statement than to use Append statements.
ENDSELECT.

Single-line Inserts Array Insert


Ravi K Page 1 4/8/2009
TIPS & TRICKS
LOOP AT TAB INTO TAB_WA.
INSERT INTO CUSTOMERS VALUES TAB_WA. INSERT CUSTOMERS FROM TABLE TAB.
ENDLOOP.

Whenever possible, use array operations instead of single-row


operations to modify your database tables. Frequent
communication between the application program and database
system produces considerable overhead.
Select Into Table t + Loop at t. Select ... Endselect.
SELECT * FROM T006 SELECT * FROM T006 INTO X006_WA.
INTO TABLE X006. ENDSELECT.
LOOP AT X006 INTO X006_WA.
ENDLOOP.

If you process your data only once, use a Select-Endselect-loop


instead of collecting data in an internal table with Select Into
Table. Internal table handling takes up much more space.
Nested Select statements Select with view
SELECT * FROM DD01L INTO DD01L_WA SELECT * FROM DD01V INTO DD01V_WA
WHERE DOMNAME LIKE 'CHAR%' WHERE DOMNAME LIKE 'CHAR%'
AND AS4LOCAL = 'A'. AND DDLANGUAGE = SY-LANGU.
SELECT SINGLE * FROM DD01T INTO DD01T_WA ENDSELECT.
WHERE DOMNAME = DD01L_WA-DOMNAME
AND AS4LOCAL = 'A' To process a join, use a view instead of nested Select
AND AS4VERS = DD01L_WA-AS4VERS statements.
AND DDLANGUAGE = SY-LANGU. Network load is considerably less.
ENDSELECT.
Nested Select statements Select with join
SELECT * FROM SPFLI INTO SPFLI_WA. SELECT * INTO WA
SELECT * FROM SFLIGHT INTO SFLIGHT_WA FROM SPFLI AS P INNER JOIN SFLIGHT AS F
WHERE CARRID = SPFLI_WA-CARRID ON P~CARRID = F~CARRID AND
AND CONNID = SPFLI_WA-CONNID. P~CONNID = F~CONNID.
ENDSELECT. ENDSELECT.
ENDSELECT.

To read data from several logically connected tables use a join


instead of nested Select statements. Network load is
considerably less.
Using Two Selects Using A Sub query
SELECT * FROM SPFLI SELECT * FROM SFLIGHT AS F INTO SFLIGHT_WA
INTO TABLE T_SPFLI WHERE SEATSOCC < F~SEATSMAX
WHERE CITYFROM = 'FRANKFURT' AND EXISTS ( SELECT * FROM SPFLI
AND CITYTO = 'NEW YORK'. WHERE CARRID = F~CARRID
SELECT * FROM SFLIGHT AS F AND CONNID = F~CONNID
INTO SFLIGHT_WA AND CITYFROM = 'FRANKFURT'
FOR ALL ENTRIES IN T_SPFLI AND CITYTO = 'NEW YORK' AND FLDATE
WHERE SEATSOCC < F~SEATSMAX BETWEEN
AND CARRID = T_SPFLI-CARRID '19990101' AND '19990331'.
AND CONNID = T_SPFLI-CONNID ENDSELECT.
AND FLDATE BETWEEN '19990101' AND '19990331'.
ENDSELECT.

Instead of using nested Select loops or FOR ALL ENTRIES it is


often possible to use sub queries.
Network load is considerably less.
SELECT Context (for durable data)
SELECT * FROM SBOOK INTO SBOOK_WA UP TO 10 SELECT * FROM SBOOK INTO SBOOK_WA UP TO 10
ROWS. ROWS.
SELECT SINGLE AIRPFROM AIRPTO SUPPLY CARRID = SBOOK_WA-CARRID
INTO (AP1, AP2) CONNID = SBOOK_WA-CONNID
FROM SPFLI TO CONTEXT TRAV1.
WHERE CARRID = SBOOK_WA-CARRID DEMAND AIRPFROM = AP1
AND CONNID = SBOOK_WA-CONNID. AIRPTO = AP2
SELECT SINGLE NAME NAME_FROM = NAME1
INTO NAME1 NAME_TO = NAME2
FROM SAIRPORT FROM CONTEXT TRAV1.

Ravi K Page 2 4/8/2009


TIPS & TRICKS
WHERE ID = AP1. ENDSELECT.
SELECT SINGLE NAME
INTO NAME2
Context advantages:
FROM SAIRPORT - no double fetch by DEMAND: 1. fetch, 2. get from buffer
WHERE ID = AP2. - more performance (best SELECT-statement)
ENDSELECT. - better survey of code

Linear search in an internal table Binary search in an internal table


* Entries: 1000, Line width: 100 * Entries: 1000, Line width: 100
* Key width: 20 * Key width: 20
* The READ ends with SY-SUBRC=4 * The READ ends with SY-SUBRC=4

READ TABLE ITAB INTO WA READ TABLE ITAB INTO WA


WITH KEY K = 'X'. WITH KEY K = 'X'
BINARY SEARCH.
If internal tables are assumed to have many (>20) entries, a
linear
search through all entries is very time-consuming.
Try to keep the table ordered and use binary search
or used a table of type SORTED TABLE.
If TAB has n entries, linear search runs in O( n ) time, whereas
binary search takes only O( log2( n ) ).
Dynamically specified key Statically specified key
READ TABLE ITAB INTO WA READ TABLE ITAB INTO WA
WITH KEY (NAME) = 'X'. WITH KEY K = 'X'.

A dynamic key access is slower than a static one, since the key
specification must be evaluated at runtime. However, for large
tables the costs are dominated by number of comparison
needed to locate the entry.
No secondary index => linear search Binary search using secondary index
READ TABLE ITAB INTO WA READ TABLE SEC_IDX INTO SEC_IDX_WA
WITH KEY DATE = SY-DATUM. WITH KEY DATE = SY-DATUM
IF SY-SUBRC = 0. BINARY SEARCH.
" ... IF SY-SUBRC = 0.
ENDIF. READ TABLE ITAB INTO WA
INDEX SEC_IDX_WA-INDX.
If you need to access an internal table with different keys " ...
repeatedly, keep your own secondary indices. ENDIF.
With a secondary index, you can replace a linear search with a
binary search plus an index access.

Key access with LOOP/CHECK Key access with LOOP ... WHERE
LOOP AT ITAB INTO WA. LOOP AT ITAB INTO WA WHERE K = 'X'.
CHECK WA-K = 'X'. " ...
" ... ENDLOOP.
ENDLOOP.

LOOP ... WHERE is faster than LOOP/CHECK because LOOP


... WHERE evaluates the specified condition internally.
As with any logical expressions, the performance is better if the
operands of a comparison share a common type.
The performance can be further enhanced if LOOP ... WHERE
is combined with FROM i1 and/or TO i2, if possible.
READ on a unique sorted table READ on a unique hashed table
DO 250 TIMES. DO 250 TIMES.
N = 4 * SY-INDEX. N = 4 * SY-INDEX.
READ TABLE STAB INTO WA WITH TABLE KEY K = N. READ TABLE HTAB INTO WA WITH TABLE KEY K = N.
IF SY-SUBRC = 0. IF SY-SUBRC = 0.
" ... " ...
ENDIF. ENDIF.
ENDDO. ENDDO.

Entries in a sorted table are located by binary search. Hashed tables are optimized for single entry access, whereas
The costs depend on the number of entries in the table (O (log sorted tables are optimized for partial sequential loop

Ravi K Page 3 4/8/2009


TIPS & TRICKS
n)). Entries in a hashed table are located by an internal hash- operations (see the
algorithm .The costs are constant (O (1)), i.e. they do not separate example).
depend on the table size.

Partial sequential access on a sorted table Partial sequential access on a sorted table
LOOP AT HTAB INTO WA WHERE K = SUBKEY. LOOP AT STAB INTO WA WHERE K = SUBKEY.
" ... " ...
ENDLOOP. ENDLOOP.
Hashed tables are optimized for single entry access. The Sorted tables are ordered ascendingly by their key
entries have no specific order. Therefore, a partial sequential components. If a partial key of the form "k1 = v1 AND ... AND
access cannot be optimized. Every entry must be checked to kn = vn" where k1... kn
match the condition matches a left part of the table key, the access is optimized by
(full table scan). the kernel. In that case, only the matching entries are visited.
One-step approach Three-steps: move, sort, delete dupl.
ITAB2[] = ITAB1[].
REFRESH ITAB2. SORT ITAB2 BY K.
LOOP AT ITAB1 INTO WA. DELETE ADJACENT DUPLICATES FROM ITAB2
READ TABLE ITAB2 WITH KEY K = WA-K COMPARING K.
BINARY SEARCH
TRANSPORTING NO FIELDS.
IF SY-SUBRC <> 0.
INSERT WA INTO ITAB2
INDEX SY-TABIX.
ENDIF.
ENDLOOP.

If the data amount is small (< 20 entries), or if you need read-


access to the internal table while it is being filled, the one-step
approach using READ/INSERT is the right choice.
If, however, the data amount is larger and you need read-
access only to the completely-filled table, the three-step
algorithm is preferable.
See also the comparable test for SORTED vs. HASHED
TABLEs
INSERT in a sorted table with unique key INSERT in a hashed table with unique key
REFRESH ITAB2. REFRESH ITAB2.
LOOP AT ITAB1 INTO WA. LOOP AT ITAB1 INTO WA.
INSERT WA INTO TABLE ITAB2. INSERT WA INTO TABLE ITAB2.
IF SY-SUBRC <> 0. IF SY-SUBRC <> 0.
" ... " ...
ENDIF. ENDIF.
ENDLOOP. ENDLOOP.

You can use the same syntax (generic INSERT ... INTO TABLE Filling a hash table is faster than for a sorted table. You can
...) for different types of tables (SORTED, HASHED). access single entries very fast, but partial sequential loops are
Filling a sorted table is equivalent to building it up by "READ more expensive than for sorted tables (see the separate
BINARY SEARCH" and "INSERT ... INDEX SY-TABIX" but it is example).
slightly faster and more elegant to use the generic "INSERT ...
INTO TABLE ...". See the example for building a unique
standard table, if you need no access to the table while it is
build up.
Modifying the complete line Modifying selected components only
WA-DATE = SY-DATUM. WA-DATE = SY-DATUM.
MODIFY ITAB FROM WA INDEX 1. MODIFY ITAB FROM WA INDEX 1 TRANSPORTING
DATE.
With the MODIFY variant "MODIFY itab ... TRANSPORTING f1
f2 ..." the task of updating a line of an internal table can be
accelerated.
The longer the table line is, the larger the speed-up is. The
effect increases for tables with complex structured line types.
Modifying all lines completely Modifying selected components only
LOOP AT ITAB INTO WA. LOOP AT ITAB ASSIGNING <WA>.
I = SY-TABIX MOD 2. I = SY-TABIX MOD 2.
IF I = 0. IF I = 0.
WA-FLAG = 'X'. <WA>-FLAG = 'X'.
Ravi K Page 4 4/8/2009
TIPS & TRICKS
MODIFY ITAB FROM WA. ENDIF.
ENDIF. ENDLOOP.
ENDLOOP.
Accessing the table entries directly in a "LOOP ... ASSIGNING
..." accelerates the task of updating a set of lines of an internal
table considerably. Especially if inner tables must not be moved
the speed-up is high.

Bottom-up strategy Top-down strategy


* Entries:50(outer table),10(inner tables) DO 50 TIMES.
* Line width: 500 (outer), 4 (inner) APPEND INITIAL LINE TO ITAB.
ENDDO.
LOOP AT ITAB ASSIGNING <F>.
DO 50 TIMES. DO 10 TIMES.
CLEAR WA. APPEND N TO <F>-INTTAB.
DO 10 TIMES. ADD 1 TO N.
APPEND N TO WA-INTTAB. ENDDO.
ADD 1 TO N. ENDLOOP.
ENDDO.
APPEND WA TO ITAB. On the contrary, the top-down strategy fills the outer tables first
ENDDO. and updates the inner tables directly by using "LOOP ...
ASSIGNING".
That is, the contents of inner tables are only moved once.
Filling an internal table with the bottom-up strategy, you have to
pay move costs several times depending on the depth of the
data structure. The contents of nested inner tables are moved to
every
super ordinate level of the data structure.
COLLECT semantics using READ BINARY Collect via COLLECT
LOOP AT ITAB1 INTO WA1.
READ TABLE ITAB2 INTO WA2 WITH KEY K = WA1-K
BINARY SEARCH. LOOP AT ITAB1 INTO WA.
IF SY-SUBRC = 0. COLLECT WA INTO ITAB2.
ADD: WA1-VAL1 TO WA2-VAL1, ENDLOOP.
WA1-VAL2 TO WA2-VAL2. SORT ITAB2 BY K.
MODIFY ITAB2 FROM WA2 INDEX SY-TABIX
TRANSPORTING VAL1 VAL2. If you need the COLLECT semantics, DO use COLLECT !
ELSE. READ BINARY runs in O( log2(n) ) time, and the internal
INSERT WA1 INTO ITAB2 INDEX SY-TABIX. table's index must be adjusted with each INSERT.
ENDIF. COLLECT, however, uses a hash algorithm and is therefore
ENDLOOP. independent of the number of entries (i.e. O(1)) and does not
need to maintain a table index. If you need the final data
sorted, sort it after
all data has been collected.
If the amount of data is small, the READ/INSERT approach
isn't bad, but for large amounts of data (> 1000), COLLECT is
much faster.
Caution: When you fill an internal table, do not use COLLECT
in combination with any other table-filling statements
(APPEND, INSERT, MODIFY, SELECT * INTO TABLE and/or
SELECT * APPENDING TABLE). If you mix COLLECT with the
other statements, COLLECT cannot use its hash
algorithm. In this case, COLLECT resorts to a normal linear
search, which is dramatically slower: O(n).
Array operations Let the kernel do the work
Pedestrian way to append a table
* ITAB1 is appended in one step to ITAB2.

* ITAB1 is appended line by line to ITAB2. APPEND LINES OF ITAB1 TO ITAB2.

LOOP AT ITAB1 INTO WA.


APPEND WA TO ITAB2.
ENDLOOP.

With the APPEND variant "APPEND LINES OF itab1 TO itab2"


the task of appending a table to another table can be
transferred to the kernel.

Ravi K Page 5 4/8/2009


TIPS & TRICKS
Pedestrian way to insert a table Let the kernel do the work
* ITAB1 is inserted line by line into ITAB2 at index I. * ITAB1 is inserted in one step into ITAB2 at index IDX.

I = 250. I = 250.
LOOP AT ITAB1 INTO WA. INSERT LINES OF ITAB1 INTO ITAB2
INSERT WA INTO ITAB2 INDEX I. INDEX I.
ADD 1 TO I.
ENDLOOP.

With the INSERT variant "INSERT LINES OF itab1 INTO itab2


INDEX idx" the task of inserting a table into another table can
be transferred to the kernel.

Pedestrian way to delete duplicates Let the kernel do the work


READ TABLE ITAB INDEX 1 INTO PREV_LINE. DELETE ADJACENT DUPLICATES FROM ITAB
LOOP AT ITAB FROM 2 INTO WA. COMPARING K.
IF WA = PREV_LINE.
DELETE ITAB. With the DELETE variant "DELETE ADJACENT
ELSE. DUPLICATES" the task of deleting duplicate entries can be
PREV_LINE = WA. transferred to the
ENDIF. kernel.
ENDLOOP.
Pedestrian way to delete a seq. of lines Let the kernel do the work
* Range to be deleted: 450... 550
DELETE ITAB FROM 450 TO 550.
DO 101 TIMES.
DELETE ITAB INDEX 450.
ENDDO.

With the DELETE variant "DELETE itab FROM ... TO ..." the
task of deleting a sequence of lines can be transferred to the
kernel.
Pedestrian way to copy internal tables Let the kernel do the work
REFRESH ITAB2.
LOOP AT ITAB1 INTO WA. ITAB2[] = ITAB1[].
APPEND WA TO ITAB2.
ENDLOOP. Internal tables can be copied by MOVE just like any other data
object.
If an internal table itab has a header line, the table itself is
accessed by itab[].
Pedestrian way to compare int. tables Let the kernel do the work ...
* Both tables have the same contents
* Both tables have the same contents
DESCRIBE TABLE: ITAB1 LINES L1,
ITAB2 LINES L2. IF ITAB1[] = ITAB2[].
" ...
IF L1 <> L2. ENDIF.
TAB_DIFFERENT = 'X'.
ELSE.
TAB_DIFFERENT = SPACE.
LOOP AT ITAB1 INTO WA1.
READ TABLE ITAB2 INTO WA2 INDEX SY-TABIX. Internal tables can be compared in logical expressions just like
IF WA1 <> WA2.
TAB_DIFFERENT = 'X'. EXIT. other data objects.
ENDIF. Two internal tables are equal if
ENDLOOP. - they have the same number of lines and
ENDIF. - each pair of corresponding lines is equal.
IF TAB_DIFFERENT = SPACE. If an internal table itab has a header line, the table itself is
" ... accessed by itab[].
ENDIF.

Sort int. table with default sort key Sort with sort key specified explicitly
SORT ITAB. SORT ITAB BY K.
The more restrictively you specify the sort key, the faster the
program will run.

Ravi K Page 6 4/8/2009


TIPS & TRICKS
Therefore, specify the sort key as restrictively as possible.
Naive join: loop ITAB1, read ITAB2 w/key More sophisticated: use parallel cursors
DATA: I TYPE I.
* Both tables sorted by unique key K ascending
I = 1.
LOOP AT ITAB1 INTO WA1.
LOOP AT ITAB1 INTO WA1.
do.
READ TABLE ITAB2 INTO WA2
READ TABLE ITAB2 INTO WA2 INDEX I.
WITH KEY K = WA1-K BINARY SEARCH.
IF SY-SUBRC <> 0. EXIT. ENDIF.
IF SY-SUBRC = 0.
IF WA2-K < WA1-K.
" ...
ADD 1 TO I.
ENDIF.
ELSEIF WA2-K = WA1-K.
ENDLOOP.
" ...
ADD 1 TO I.
If ITAB1 has n1 entries and ITAB2 has n2 entries, the time
needed for joining ITAB1 and ITAB2 with the straightforward EXIT.
algorithm is O( n1 * log2( n2 ) ), whereas the parallel cursor ELSE.
approach takes only EXIT.
O( n1 + n2 ) time. endif.
The above parallel cursor algorithm assumes that ITAB2 is a enddo.
secondary table containing only entries also contained in if sy-subrc <> 0. exit. endif.
primary table ITAB1. ENDLOOP.
If this assumption does not hold, the parallel cursor algorithm
gets slightly more complicated, but its performance
characteristics remain the same.
Straightforward nested loop More sophisticated loop: parallel cursors
I = 1.
* Both tables sorted by key K LOOP AT ITAB1 INTO WA1.
LOOP AT ITAB2 INTO WA2 FROM I.
LOOP AT ITAB1 INTO WA1. IF WA2-K <> WA1-K.
LOOP AT ITAB2 INTO WA2 I = SY-TABIX.
WHERE K = WA1-K. EXIT.
" ... ENDIF.
ENDLOOP. " ...
ENDLOOP. ENDLOOP.
ENDLOOP.
The above parallel cursor algorithm assumes that ITAB2
If ITAB1 has n1 entries and ITAB2 has n2 entries, the time contains only entries also contained in ITAB1.
needed for the nested loop with the straightforward algorithm is If this assumption does not hold, the parallel cursor algorithm
O(n1 * n2), gets slightly more complicated, but its performance
whereas the parallel cursor approach takes only O(n1 + n2) characteristics remain the same.
time.
Using a sorted table temporarily Using a hashed table temporarily
* Entries: 200 (ITAB1), 100 (ITAB2)
* Intersection: 50 (ITAB3) HTAB1 = ITAB1.
* Line width: 100, Key width: 20 REFRESH ITAB3.
LOOP AT ITAB2 ASSIGNING <WA>.
STAB1 = ITAB1. READ TABLE HTAB1 FROM <WA>
REFRESH ITAB3. TRANSPORTING NO FIELDS.
LOOP AT ITAB2 ASSIGNING <WA>. IF SY-SUBRC = 0.
READ TABLE STAB1 FROM <WA> APPEND <WA> TO ITAB3.
TRANSPORTING NO FIELDS. ENDIF.
IF SY-SUBRC = 0. ENDLOOP.
APPEND <WA> TO ITAB3. FREE HTAB1.
ENDIF.
ENDLOOP.
FREE STAB1.

The source tables ITAB1 and ITAB2 are standard tables. It is


assumed that ITAB1 takes more entries than ITAB2. Otherwise,
the table with more entries must be computed with "DESCRIBE
TABLE ... LINES ...”
Since both tables shall represent sets, it is assumed that their
entries are unique with respect to component K.
The algorithm works with a temporary table with unique key K.
The table is a copy of ITAB1 and is used to locate the entries
being also contained in ITAB2. The matching entries are copied
to ITAB3.
The left-hand and right-hand side differ only by the kind of the
Ravi K Page 7 4/8/2009
TIPS & TRICKS
temporary table being used. For a hashed table, the READ
statement in the LOOP is faster than for the sorted table.
Untyped parameters Typed parameters
PERFORM UP1 USING 10 M6-DIMID M6-ZAEHL M6- PERFORM UP2 USING 10 M6-DIMID M6-ZAEHL M6-
ISOCODE M6-ANDEC M6-PRIMARY. ISOCODE M6-ANDEC M6-PRIMARY.

FORM UP1 USING FORM UP2 USING


REPEAT REPEAT TYPE I
DIMID DIMID LIKE T006-DIMID
ZAEHL ZAEHL LIKE T006-ZAEHL
ISOCODE ISOCODE LIKE T006-ISOCODE
ANDEC ANDEC LIKE T006-ANDEC
PRIMARY. PRIMARY LIKE T006-PRIMARY.
* Identical source code left and right: * Identical source code left and right:
DO REPEAT TIMES. DO REPEAT TIMES.
T006_WA-DIMID = DIMID. T006_WA-DIMID = DIMID.
T006_WA-ZAEHL = ZAEHL. T006_WA-ZAEHL = ZAEHL.
T006_WA-ISOCODE = ISOCODE. T006_WA-ISOCODE = ISOCODE.
T006_WA-ANDEC = ANDEC. T006_WA-ANDEC = ANDEC.
T006_WA-PRIMARY = PRIMARY. T006_WA-PRIMARY = PRIMARY.
ENDDO. ENDDO.
ENDFORM. ENDFORM.

If you specify the type for formal parameters in your source


code, the ABAP/4 compiler can optimize your code more
thoroughly.
In addition, the risk of using the wrong sequence of parameters
in a Perform statement is much less.
Field-Symbol without type Typed Field-Symbol
FIELD-SYMBOLS: <F> TYPE ANY. FIELD-SYMBOLS: <I> TYPE I.
DATA: I1 TYPE I, I2 TYPE I. DATA: I1 TYPE I, I2 TYPE I.

ASSIGN I1 TO <F>. ASSIGN I1 TO <I>.

I2 = <F>. I2 = <I>.

If you specify the type of field-symbols and formal parameters in


your source code, the ABAP/4 compiler can better optimize your
code.
If Case
DATA C TYPE C. DATA C TYPE C.
IF C = 'A'. WRITE '1'. CASE C.
ELSEIF C = 'B'. WRITE '2'. WHEN 'A'. WRITE '1'.
ELSEIF C = 'C'. WRITE '3'. WHEN 'B'. WRITE '2'.
ELSEIF C = 'D'. WRITE '4'. WHEN 'C'. WRITE '3'.
ELSEIF C = 'E'. WRITE '5'. WHEN 'D'. WRITE '4'.
ELSEIF C = 'F'. WRITE '6'. WHEN 'E'. WRITE '5'.
ELSEIF C = 'G'. WRITE '7'. WHEN 'F'. WRITE '6'.
ELSEIF C = 'H'. WRITE '8'. WHEN 'G'. WRITE '7'.
ENDIF. WHEN 'H'. WRITE '8'.
ENDCASE.
CASE statements are clearer and a little faster than
IF-constructions.
IF i = c. IF c = c.
DATA C(8) TYPE C. DATA C(8) TYPE C.
IF 12345678 = C. IF '12345678' = C.
ENDIF. ENDIF.
Comparing C with C its faster as comparing C with a great Comparing C with C its faster as comparing C with a great
number number
Do While
DATA C TYPE C. DATA I TYPE I. DATA C TYPE C. DATA I TYPE I.
I = 0. I = 0.
DO. WHILE C = SPACE.
IF C NE SPACE. EXIT. ENDIF. ADD 1 TO I.
ADD 1 TO I. IF I GT 10. C = 'X'. ENDIF.
IF I GT 10. C = 'X'. ENDIF. ENDWHILE.
ENDDO.

Ravi K Page 8 4/8/2009


TIPS & TRICKS
If you can use WHILE instead of a DO+EXIT-construction, then
do so.
WHILE is easier to understand and faster to execute.
Case Perform i Of ...
* (I = 5 in this test) * (I = 5 in this test)
CASE I. PERFORM I OF
WHEN 1. PERFORM PV1. PV1
WHEN 2. PERFORM PV2. PV2
WHEN 3. PERFORM PV3. PV3
WHEN 4. PERFORM PV4. PV4
WHEN 5. PERFORM PV5. PV5
WHEN 6. PERFORM PV6. PV6
WHEN 7. PERFORM PV7. PV7
WHEN 8. PERFORM PV8. PV8.
ENDCASE.

A very fast way to call a certain routine using a given


index is the Perform i Of ... statement.
FIELD CONVERSION
Type P Type I
DATA P TYPE P VALUE 1.
DATA I TYPE I VALUE 1.
READ TABLE TAB INTO TAB_WA INDEX P.
READ TABLE TAB INTO TAB_WA INDEX I.
Use fields of type I for typical integral variables like indices.

Type C Type I
MOVE SPACE TO SY-SUBRC. SY-SUBRC = 0.
CASE SY-SUBRC. CASE SY-SUBRC.
WHEN '1'. WHEN 1.
WHEN '2'. WHEN 2.
WHEN '3'. WHEN 3.
WHEN '4'. WHEN 4.
ENDCASE. ENDCASE.

Use numeric literals or named constants with a number type


instead of character strings if you are dealing with type-I
or integral type-P fields.
Literal Type C Constant Type F
DATA: CONSTANTS:
FLOAT TYPE F. PI TYPE F VALUE '3.1415926535897932'.
DATA: FLOAT TYPE F.
FLOAT = '3.1415926535897932'. FLOAT = PI.

Use properly typed constants instead of literals.


Type N Type P
DATA: DATA:
N1(15) TYPE N VALUE '123456789012345', P1 TYPE P VALUE '123456789012345',
N2(15) TYPE N VALUE '543210987654321', P2 TYPE P VALUE '543210987654321',
N3(15) TYPE N. P3 TYPE P.

N3 = N1 + N2. P3 = P1 + P2.

Use number types for arithmetic. Use type-N fields only for pure
digit strings that are not intended for calculations, e.g.,
telephone numbers or parts of a date or time field.

Several Types Only One Type


DATA: F1 TYPE I VALUE 2, DATA: F1 TYPE F VALUE 2,
F2 TYPE P DECIMALS 2 VALUE '3.14', F2 TYPE F VALUE '3.14',
F3 TYPE F. F3 TYPE F.

F3 = F1 * F2. F3 = F1 * F2.

Ravi K Page 9 4/8/2009


TIPS & TRICKS
Don't mix types unless absolutely necessary.

Character fields (fixed length) String (unfixed length)


*data c1(200) type c. *data string1 type string.
*data c2(200) type c. *data string2 type string.
*data c3(400) type c. *data string3 type string.

c1 = 'mysap'. string1 = 'mysap'.


c2 = '.com'. string2 = '.com'.
concatenate c1 c2 into c3. concatenate string1 string2 into string3.

Depending on the length of the character field,


string operation may be faster.
The concatenate algorithm has to compute the length of the
fixed character fields by scanning the first non-blank character
from the end.
Calling local Subroutines Calling Methods of local Classes
call method C1=>M1.
perform F1.
There is no performance loss when you call local methods
compared to local subroutines.
Calling Function Modules Calling Methods of global Classes
call function 'FUNCTION1'. call method CL_PERFORMANCE_TEST=>M1.

Calling methods of global classes is faster than calling function


modules .
Calling local Methods Calling global Methods
call method C1=>M1. call method CL_PERFORMANCE_TEST=>M1.

Calling global methods is not much slower compared to calling


local methods .

Ravi K Page 10 4/8/2009