TIPS & TRICKS NO
YES
Select using an aggregate function DATA: MAX_MSGNR type t100-msgnr. SELECT MAX( MSGNR ) FROM T100 INTO max_msgnr WHERE SPRSL = 'D' AND ARBGB = '00'.
DATA: MAX_MSGNR type t100-msgnr. MAX_MSGNR = '000'. SELECT * FROM T100 INTO T100_WA 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 WHERE CARRID = 'LH'. EXIT. ENDSELECT.
SELECT * FROM SBOOK INTO SBOOK_WA UP TO 1 ROWS WHERE CARRID = 'LH'. 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 = SFLIGHT_WA-SEATSOCC - 1. UPDATE SFLIGHT FROM SFLIGHT_WA. ENDSELECT.
UPDATE SFLIGHT SET SEATSOCC = SEATSOCC - 1.
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 SBOOK_WA WHERE CARRID = 'LH' AND CONNID = '0400'. ENDSELECT. For all frequently used Select statements, try to use an index. 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 * FROM SBOOK CLIENT SPECIFIED INTO SBOOK_WA WHERE MANDT IN ( SELECT MANDT FROM T000 ) AND CARRID = 'LH' AND CONNID = '0400'. ENDSELECT.
Select without buffer support
Select with buffer support
SELECT SINGLE * FROM T100 INTO T100_WA BYPASSING BUFFER WHERE SPRSL = 'D' AND ARBGB = '00' AND MSGNR = '999'. For all frequently used, read-only tables, try to use SAP buffering. Network load is considerably less.
SELECT SINGLE * FROM T100 INTO T100_WA WHERE SPRSL = 'D' AND ARBGB = '00' AND MSGNR = '999'.
Select + Append statement
Select Into Table
DATA T006_WA TYPE T006. CLEAR X006. SELECT * FROM T006 INTO T006_WA. APPEND T006_WA TO X006. ENDSELECT.
SELECT * FROM T006 INTO TABLE X006.
Single-line Inserts
Array Insert
Ravi K
It is always faster to use the Into Table version of a Select statement than to use Append statements.
Page 1
4/8/2009
TIPS & TRICKS LOOP AT TAB INTO TAB_WA. INSERT INTO CUSTOMERS VALUES TAB_WA. ENDLOOP.
INSERT CUSTOMERS FROM TABLE TAB.
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 INTO TABLE X006. LOOP AT X006 INTO X006_WA. ENDLOOP.
SELECT * FROM T006 INTO X006_WA. ENDSELECT.
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 WHERE DOMNAME LIKE 'CHAR%' AND AS4LOCAL = 'A'. SELECT SINGLE * FROM DD01T INTO DD01T_WA WHERE DOMNAME = DD01L_WA-DOMNAME AND AS4LOCAL = 'A' AND AS4VERS = DD01L_WA-AS4VERS AND DDLANGUAGE = SY-LANGU. ENDSELECT.
SELECT * FROM DD01V INTO DD01V_WA WHERE DOMNAME LIKE 'CHAR%' AND DDLANGUAGE = SY-LANGU. ENDSELECT.
Nested Select statements
Select with join
SELECT * FROM SPFLI INTO SPFLI_WA. SELECT * FROM SFLIGHT INTO SFLIGHT_WA WHERE CARRID = SPFLI_WA-CARRID AND CONNID = SPFLI_WA-CONNID. ENDSELECT. ENDSELECT.
SELECT * INTO WA FROM SPFLI AS P INNER JOIN SFLIGHT AS F ON P~CARRID = F~CARRID AND P~CONNID = F~CONNID. ENDSELECT.
To process a join, use a view instead of nested Select statements. Network load is considerably less.
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 INTO TABLE T_SPFLI WHERE CITYFROM = 'FRANKFURT' AND CITYTO = 'NEW YORK'. SELECT * FROM SFLIGHT AS F INTO SFLIGHT_WA FOR ALL ENTRIES IN T_SPFLI WHERE SEATSOCC < F~SEATSMAX AND CARRID = T_SPFLI-CARRID AND CONNID = T_SPFLI-CONNID AND FLDATE BETWEEN '19990101' AND '19990331'. ENDSELECT.
SELECT * FROM SFLIGHT AS F INTO SFLIGHT_WA WHERE SEATSOCC < F~SEATSMAX AND EXISTS ( SELECT * FROM SPFLI WHERE CARRID = F~CARRID AND CONNID = F~CONNID AND CITYFROM = 'FRANKFURT' AND CITYTO = 'NEW YORK' 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 ROWS. SELECT SINGLE AIRPFROM AIRPTO INTO (AP1, AP2) FROM SPFLI WHERE CARRID = SBOOK_WA-CARRID AND CONNID = SBOOK_WA-CONNID. SELECT SINGLE NAME INTO NAME1 FROM SAIRPORT
SELECT * FROM SBOOK INTO SBOOK_WA UP TO 10 ROWS. SUPPLY CARRID = SBOOK_WA-CARRID CONNID = SBOOK_WA-CONNID TO CONTEXT TRAV1. DEMAND AIRPFROM = AP1 AIRPTO = AP2 NAME_FROM = NAME1 NAME_TO = NAME2 FROM CONTEXT TRAV1.
Ravi K
Page 2
4/8/2009
TIPS & TRICKS WHERE ID = AP1. SELECT SINGLE NAME INTO NAME2 FROM SAIRPORT WHERE ID = AP2. ENDSELECT.
ENDSELECT.
Linear search in an internal table
Binary search in an internal table
* Entries: 1000, Line width: 100 * Key width: 20 * The READ ends with SY-SUBRC=4
* Entries: 1000, Line width: 100 * Key width: 20 * The READ ends with SY-SUBRC=4
READ TABLE ITAB INTO WA WITH KEY K = 'X'.
READ TABLE ITAB INTO WA WITH KEY K = 'X' BINARY SEARCH.
Context advantages: - no double fetch by DEMAND: 1. fetch, 2. get from buffer - more performance (best SELECT-statement) - better survey of code
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 WITH KEY (NAME) = 'X'.
READ TABLE ITAB INTO WA 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 WITH KEY DATE = SY-DATUM. IF SY-SUBRC = 0. " ... ENDIF.
READ TABLE SEC_IDX INTO SEC_IDX_WA WITH KEY DATE = SY-DATUM BINARY SEARCH. IF SY-SUBRC = 0. READ TABLE ITAB INTO WA INDEX SEC_IDX_WA-INDX. " ... ENDIF.
If you need to access an internal table with different keys repeatedly, keep your own secondary indices. 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. CHECK WA-K = 'X'. " ... ENDLOOP.
LOOP AT ITAB INTO WA WHERE K = 'X'. " ... 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. N = 4 * SY-INDEX. READ TABLE STAB INTO WA WITH TABLE KEY K = N. IF SY-SUBRC = 0. " ... ENDIF. ENDDO.
DO 250 TIMES. N = 4 * SY-INDEX. READ TABLE HTAB INTO WA WITH TABLE KEY K = N. IF SY-SUBRC = 0. " ... ENDIF. ENDDO.
Entries in a sorted table are located by binary search. The costs depend on the number of entries in the table (O (log
Hashed tables are optimized for single entry access, whereas 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 hashalgorithm .The costs are constant (O (1)), i.e. they do not depend on the table size.
operations (see the separate example).
Partial sequential access on a sorted table
Partial sequential access on a sorted table
LOOP AT HTAB INTO WA WHERE K = SUBKEY. " ... ENDLOOP. Hashed tables are optimized for single entry access. The entries have no specific order. Therefore, a partial sequential access cannot be optimized. Every entry must be checked to match the condition (full table scan).
LOOP AT STAB INTO WA WHERE K = SUBKEY. " ... ENDLOOP. Sorted tables are ordered ascendingly by their key components. If a partial key of the form "k1 = v1 AND ... AND kn = vn" where k1... kn matches a left part of the table key, the access is optimized by the kernel. In that case, only the matching entries are visited.
One-step approach
Three-steps: move, sort, delete dupl. ITAB2[] = ITAB1[]. SORT ITAB2 BY K. DELETE ADJACENT DUPLICATES FROM ITAB2 COMPARING K.
REFRESH ITAB2. LOOP AT ITAB1 INTO WA. READ TABLE ITAB2 WITH KEY K = WA-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 readaccess 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 readaccess 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. LOOP AT ITAB1 INTO WA. INSERT WA INTO TABLE ITAB2. IF SY-SUBRC <> 0. " ... ENDIF. ENDLOOP.
REFRESH ITAB2. LOOP AT ITAB1 INTO WA. INSERT WA INTO TABLE ITAB2. IF SY-SUBRC <> 0. " ... ENDIF. ENDLOOP.
You can use the same syntax (generic INSERT ... INTO TABLE ...) for different types of tables (SORTED, HASHED). Filling a sorted table is equivalent to building it up by "READ BINARY SEARCH" and "INSERT ... INDEX SY-TABIX" but it is 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.
Filling a hash table is faster than for a sorted table. You can access single entries very fast, but partial sequential loops are more expensive than for sorted tables (see the separate example).
Modifying the complete line
Modifying selected components only
WA-DATE = SY-DATUM. MODIFY ITAB FROM WA INDEX 1.
WA-DATE = SY-DATUM. MODIFY ITAB FROM WA INDEX 1 DATE.
TRANSPORTING
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. I = SY-TABIX MOD 2. IF I = 0. WA-FLAG = 'X'.
LOOP AT ITAB ASSIGNING <WA>. I = SY-TABIX MOD 2. IF I = 0. <WA>-FLAG = 'X'.
Ravi K
Page 4
4/8/2009
TIPS & TRICKS MODIFY ITAB FROM WA. ENDIF. 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.
ENDIF. ENDLOOP.
Bottom-up strategy
Top-down strategy
* Entries:50(outer table),10(inner tables) * Line width: 500 (outer), 4 (inner)
DO 50 TIMES. APPEND INITIAL LINE TO ITAB. ENDDO. LOOP AT ITAB ASSIGNING . DO 10 TIMES. APPEND N TO -INTTAB. ADD 1 TO N. ENDDO. ENDLOOP.
DO 50 TIMES. CLEAR WA. DO 10 TIMES. APPEND N TO WA-INTTAB. ADD 1 TO N. ENDDO. APPEND WA TO ITAB. ENDDO.
On the contrary, the top-down strategy fills the outer tables first 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 LOOP AT ITAB1 INTO WA1. READ TABLE ITAB2 INTO WA2 WITH KEY K = WA1-K BINARY SEARCH. IF SY-SUBRC = 0. ADD: WA1-VAL1 TO WA2-VAL1, WA1-VAL2 TO WA2-VAL2. MODIFY ITAB2 FROM WA2 INDEX SY-TABIX TRANSPORTING VAL1 VAL2. ELSE. INSERT WA1 INTO ITAB2 INDEX SY-TABIX. ENDIF. ENDLOOP.
Collect via COLLECT LOOP AT ITAB1 INTO WA. COLLECT WA INTO ITAB2. ENDLOOP. SORT ITAB2 BY K. If you need the COLLECT semantics, DO use COLLECT ! READ BINARY runs in O( log2(n) ) time, and the internal table's index must be adjusted with each INSERT. COLLECT, however, uses a hash algorithm and is therefore 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 Pedestrian way to append a table
Let the kernel do the work
* ITAB1 is appended line by line to ITAB2.
APPEND LINES OF ITAB1 TO ITAB2.
* ITAB1 is appended in one step 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. LOOP AT ITAB1 INTO WA. INSERT WA INTO ITAB2 INDEX I. ADD 1 TO I. ENDLOOP.
I = 250. INSERT LINES OF ITAB1 INTO ITAB2 INDEX I.
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. LOOP AT ITAB FROM 2 INTO WA. IF WA = PREV_LINE. DELETE ITAB. ELSE. PREV_LINE = WA. ENDIF. ENDLOOP.
DELETE ADJACENT DUPLICATES FROM ITAB COMPARING K.
Pedestrian way to delete a seq. of lines
Let the kernel do the work
With the DELETE variant "DELETE ADJACENT DUPLICATES" the task of deleting duplicate entries can be transferred to the kernel.
* Range to be deleted: 450... 550 DO 101 TIMES. DELETE ITAB INDEX 450. ENDDO.
DELETE ITAB FROM 450 TO 550.
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. APPEND WA TO ITAB2. ENDLOOP.
ITAB2[] = ITAB1[].
Pedestrian way to compare int. tables
Let the kernel do the work ...
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[].
* Both tables have the same contents DESCRIBE TABLE: ITAB1 LINES L1, ITAB2 LINES L2. IF L1 <> L2. TAB_DIFFERENT = 'X'. ELSE. TAB_DIFFERENT = SPACE. LOOP AT ITAB1 INTO WA1. READ TABLE ITAB2 INTO WA2 INDEX SY-TABIX. IF WA1 <> WA2. TAB_DIFFERENT = 'X'. EXIT. ENDIF. ENDLOOP. ENDIF. IF TAB_DIFFERENT = SPACE. " ... ENDIF.
* Both tables have the same contents IF ITAB1[] = ITAB2[]. " ... ENDIF.
Internal tables can be compared in logical expressions just like other data objects. Two internal tables are equal if - they have the same number of lines and - each pair of corresponding lines is equal. If an internal table itab has a header line, the table itself is accessed by itab[].
Sort int. table with default sort key
Sort with sort key specified explicitly
SORT ITAB. The more restrictively you specify the sort key, the faster the program will run.
SORT ITAB BY K.
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. do. READ TABLE ITAB2 INTO WA2 INDEX I. IF SY-SUBRC <> 0. EXIT. ENDIF. IF WA2-K < WA1-K. ADD 1 TO I. ELSEIF WA2-K = WA1-K. " ... ADD 1 TO I. EXIT. ELSE. EXIT. endif. enddo. if sy-subrc <> 0. exit. endif. ENDLOOP.
LOOP AT ITAB1 INTO WA1. READ TABLE ITAB2 INTO WA2 WITH KEY K = WA1-K BINARY SEARCH. IF SY-SUBRC = 0. " ... ENDIF. ENDLOOP. If ITAB1 has n1 entries and ITAB2 has n2 entries, the time needed for joining ITAB1 and ITAB2 with the straightforward algorithm is O( n1 * log2( n2 ) ), whereas the parallel cursor approach takes only O( n1 + n2 ) time. The above parallel cursor algorithm assumes that ITAB2 is a secondary table containing only entries also contained in primary table ITAB1. 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
* Both tables sorted by key K LOOP AT ITAB1 INTO WA1. LOOP AT ITAB2 INTO WA2 WHERE K = WA1-K. " ... ENDLOOP. ENDLOOP. If ITAB1 has n1 entries and ITAB2 has n2 entries, the time needed for the nested loop with the straightforward algorithm is O(n1 * n2), whereas the parallel cursor approach takes only O(n1 + n2) time.
Using a sorted table temporarily
I = 1. LOOP AT ITAB1 INTO WA1. LOOP AT ITAB2 INTO WA2 FROM I. IF WA2-K <> WA1-K. I = SY-TABIX. EXIT. ENDIF. " ... ENDLOOP. ENDLOOP. The above parallel cursor algorithm assumes that ITAB2 contains only entries also contained in ITAB1. If this assumption does not hold, the parallel cursor algorithm gets slightly more complicated, but its performance characteristics remain the same.
Using a hashed table temporarily
* Entries: 200 (ITAB1), 100 (ITAB2) * Intersection: 50 (ITAB3) * Line width: 100, Key width: 20
HTAB1 = ITAB1. REFRESH ITAB3. LOOP AT ITAB2 ASSIGNING <WA>. READ TABLE HTAB1 FROM <WA> TRANSPORTING NO FIELDS. IF SY-SUBRC = 0. APPEND <WA> TO ITAB3. ENDIF. ENDLOOP. FREE HTAB1.
STAB1 = ITAB1. REFRESH ITAB3. LOOP AT ITAB2 ASSIGNING <WA>. READ TABLE STAB1 FROM <WA> TRANSPORTING NO FIELDS. IF SY-SUBRC = 0. APPEND <WA> TO ITAB3. 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 M6ISOCODE M6-ANDEC M6-PRIMARY.
PERFORM UP2 USING 10 M6-DIMID M6-ZAEHL M6ISOCODE M6-ANDEC M6-PRIMARY.
FORM UP1 USING REPEAT DIMID ZAEHL ISOCODE ANDEC PRIMARY. * Identical source code left and right: DO REPEAT TIMES. T006_WA-DIMID = DIMID. T006_WA-ZAEHL = ZAEHL. T006_WA-ISOCODE = ISOCODE. T006_WA-ANDEC = ANDEC. T006_WA-PRIMARY = PRIMARY. ENDDO. ENDFORM.
FORM UP2 USING REPEAT TYPE I DIMID LIKE T006-DIMID ZAEHL LIKE T006-ZAEHL ISOCODE LIKE T006-ISOCODE ANDEC LIKE T006-ANDEC PRIMARY LIKE T006-PRIMARY. * Identical source code left and right: DO REPEAT TIMES. T006_WA-DIMID = DIMID. T006_WA-ZAEHL = ZAEHL. T006_WA-ISOCODE = ISOCODE. T006_WA-ANDEC = ANDEC. T006_WA-PRIMARY = PRIMARY. ENDDO. 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: TYPE ANY. DATA: I1 TYPE I, I2 TYPE I.
FIELD-SYMBOLS: TYPE I. DATA: I1 TYPE I, I2 TYPE I.
ASSIGN I1 TO .
ASSIGN I1 TO .
I2 = .
I2 = .
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. IF C = 'A'. WRITE '1'. ELSEIF C = 'B'. WRITE '2'. ELSEIF C = 'C'. WRITE '3'. ELSEIF C = 'D'. WRITE '4'. ELSEIF C = 'E'. WRITE '5'. ELSEIF C = 'F'. WRITE '6'. ELSEIF C = 'G'. WRITE '7'. ELSEIF C = 'H'. WRITE '8'. ENDIF.
DATA C TYPE C. CASE C. WHEN 'A'. WRITE '1'. WHEN 'B'. WRITE '2'. WHEN 'C'. WRITE '3'. WHEN 'D'. WRITE '4'. WHEN 'E'. WRITE '5'. WHEN 'F'. WRITE '6'. WHEN 'G'. WRITE '7'. 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. IF 12345678 = C. ENDIF. Comparing C with C its faster as comparing C with a great number
DATA C(8) TYPE C. IF '12345678' = C. ENDIF. Comparing C with C its faster as comparing C with a great number
Do
While
DATA C TYPE C. DATA I TYPE I. I = 0. DO. IF C NE SPACE. EXIT. ENDIF. ADD 1 TO I. IF I GT 10. C = 'X'. ENDIF. ENDDO.
DATA C TYPE C. DATA I TYPE I. I = 0. WHILE C = SPACE. ADD 1 TO I. IF I GT 10. C = 'X'. ENDIF. ENDWHILE.
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) CASE I. WHEN 1. PERFORM WHEN 2. PERFORM WHEN 3. PERFORM WHEN 4. PERFORM WHEN 5. PERFORM WHEN 6. PERFORM WHEN 7. PERFORM WHEN 8. PERFORM ENDCASE.
* (I = 5 in this test) PERFORM I OF PV1 PV2 PV3 PV4 PV5 PV6 PV7 PV8.
PV1. PV2. PV3. PV4. PV5. PV6. PV7. PV8.
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. CASE SY-SUBRC. WHEN '1'. WHEN '2'. WHEN '3'. WHEN '4'. ENDCASE.
SY-SUBRC = 0. CASE SY-SUBRC. WHEN 1. WHEN 2. WHEN 3. WHEN 4. 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: FLOAT TYPE F.
CONSTANTS: PI TYPE F VALUE '3.1415926535897932'. DATA: FLOAT TYPE F. FLOAT = PI.
FLOAT = '3.1415926535897932'. Use properly typed constants instead of literals.
Type N
Type P
DATA: N1(15) TYPE N VALUE '123456789012345', N2(15) TYPE N VALUE '543210987654321', N3(15) TYPE N.
DATA: P1 TYPE P VALUE '123456789012345', P2 TYPE P VALUE '543210987654321', 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, F2 TYPE P DECIMALS 2 VALUE '3.14', F3 TYPE F.
DATA: F1 TYPE F VALUE 2, F2 TYPE F VALUE '3.14', F3 TYPE F.
F3 = F1 * F2.
Ravi K
F3 = F1 * F2.
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 c2(200) type c. *data c3(400) type c.
*data string1 type string. *data string2 type string. *data string3 type string.
c1 = 'mysap'. c2 = '.com'. concatenate c1 c2 into c3.
string1 = 'mysap'. string2 = '.com'. 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