"
Etiqueta > performance
Supported by

Pass internal tables by value is good

When a method returns a value as a RETURNING parameter this is always done by value and not by reference. Several of my methods return internal tables, some of them quite large. It always worried me the idea that, since it’s being passed by value, ABAP would be returning a copy of the internal table, impacting both performance and the program’s used memory.

Fortunately, I recently learned that this is not​ a problem.

Ler o resto do artigo! »

Internal table secondary indexes

This is how internal tables used to be declared:


DATA: itbl TYPE TABLE OF bkpf.

Ler o resto do artigo! »

DELETE vs CLEAR vs REFRESH vs FREE

DELETE
CLEAR
REFRESH
FREE

These are different ways of deleting all data from an internal table. They look the same. But they aren’t.

Ler o resto do artigo! »

Teach ABAP to juggle

What can be done when a night is not enough to complete the daily processes?

Ler o resto do artigo! »

Best practices
Thou shalt use TRANSPORTING NO FIELDS

Many times we do READ TABLE itbl or LOOP AT itbl just to do a CHECK SY-SUBRC = 0. In these cases, the actual data read is not needed. For these cases always use TRANSPORTING NO FIELDS. This way is faster and avoids having to declare a target structure.

Best practices
INNER JOIN vs FOR ALL ENTRIES vs artificial RANGES

Since data operations are much more optimized in the database server than in ABAP, it is always better to use the first as much as possible. FOR ALL ENTRIES should only be used when INNER JOIN doesn’t give us what we need or is not possible (like with BSEG for example). Artificial ranges are also a possible alternative to FOR ALL ENTRIES but be careful not to reach the SQL parser limit. It depends on the database server but as a rule of thumb avoid ranges with more than 1000 lines.
When using FOR ALL ENTRIES always make sure the internal table is not empty or else all lines of the database table will be fetched.

Best practices
Thou shalt not SELECT *

Always try to select only the fields you’ll need. Selecting others is a waste of resources.
Exception made for the use of FM *_SINGLE_READ because, even though these do select all fields, since they cache the data, they are still faster when used multiple times for the same key.
If you just want to check if a record exists, select just one field, if possible the one you’re using as criteria to avoid declaring an extra variable. Example: SELECT KUNNR INTO V_KUNNR FROM KNA1 WHERE KUNNR = V_KUNNR.
https://abapinho.com/2010/11/select-todos-os-campos/ (portuguese)

Best practices
Thou shalt use FIELD-SYMBOLs instead of working areas

READ TABLE itbl ASSIGNING is always faster than READ TABLE itbl INTO wa.
Besides, when making changes to internal tables, not only it doesn’t require the explicit MODIFY but it also does away with the auxiliary TABIX variable.
The only situation in which a working area is better is when adding new lines to an internal table.
Some people contend that working areas should still be used when no changes are to be made to the data. This is still slower, but visually can be more intuitive.

SELECT within SELECT

ABAP programmers don’t explore the possibilities of SQL, probably for historical reasons. There are many who instead of using INNER JOINs still think it’s faster to do several SELECTs for internal tables and then process the data in ABAP. But the truth is that even if there are exceptions, the rule is: the lower the number of accesses to the database, the better the performance. And it makes sense because, after all, they were written explicitly for this; relational databases are much more adept at processing relational data than an ABAP program.

There are of course things that, due to their complexity, cannot be done with a simple INNER JOIN. Nevertheless, some of these things can be done in a single SELECT.

Ler o resto do artigo! »

With many fields avoid INTO CORRESPONDING FIELDS

I have already advised here that, in tables with many fields, it’s always recommended to avoid using SELECT *, you must always select, explicitly, only the necessary fields.

But I didn’t warn you that there’s yet another optimisation worth making: avoid INTO CORRESPONDING FIELDS OF TABLE.

Ler o resto do artigo! »

SORTED instead of STANDARD in the cache tables

Some time ago I wrote a post here showing the advantages of using internal tables with defined indexes instead of simple STANDARD tables.

Confession: that habit is so ingrained that since then, almost all the internal tables I have created have continued to be STANDARD TABLE.

It’s very common to create internal tables to cache data that I know I’ll often use inside LOOPS to avoid having to SELECT SINGLES inside them.

Here is a hint: whenever you create an internal table filled with cache data, that you only write once but read many times, instead of STANDARD, consider creating it as SORTED and set it up properly with a key. It is worth it.

Now that I have confessed, I hope to be absolved and offer to change myself.

Greetings from Abapinho.

Partial Analyses in SE30

Obviously you already know the SE30 transaction (run time analysis) and obviously you use it often to analyse standard programs and to discover tables, functions, BADIs and similar contained within them.

But if you are like me, then you have a love-hate relationship with this transaction – on the one hand you love it because it enables you to see the guts of a program without having to debug it, yet on the other hand you hate it because normally the list of guts tends to have thousands of lines and becomes unmanageable.

But I am not myself any more because since I discovered that SE30 enables you to do partial analyses, my relationship with it has transformed into one of pure love. And from now on you’ll also be able to love it in its entirety because I’m going to teach you this little secret.

  1. Transaction SE30;
  2. In the block “Measurement Restrictions” create a variant with a name different from the DEFAULT;
  3. In the variant, activate “Specific Units”;
  4. Insert the transaction or program or function module to be analysed;
  5. Load in “Run” (normally now the analysis would start, but as we have selected “Specific Units”, it starts as deactivated and it has to be activated explicitly);
  6. Navigate inside the program that you are analysing until you arrive at the point that you wish to analyse;
  7. Activate the analysis by writing /ron in the top of the command field;
  8. Do what you have to do;
  9. Deactivate the analysis by writing /roff at the top;
  10. Exit the program and return to the SE30 screen.

You have just done a partial analysis, so instead of the typical thousands of lines, there are only tens or hundreds of lines which occur between the commands /ron and /roff. More useful. don’t you think?

Leverage the feature and explore other possibilities made available by “Measurement Restrictions” variants.

Thanks to Michael Opoczynski for this lesson.

And thanks to * Cati Kaoe * for the photo.

Greetings from Abapinho.

LOOP ASSIGNING instead of LOOP INTO

In the beginning there was INTO.
Actually, in the beginning it was not even INTO.

Ler o resto do artigo! »

Taking a nap

Whatever the case, it is necessary to put a program to sleep. And, as with almost everything else, there are several ways to do this, some better than others.

The most standard way to do this in ABAP is as follows:


WAIT UP TO 10 SECONDS.

The advantage of WAIT UP TO N SECONDS is that the process is freed up during these 10 seconds, thereby making it available for those who want it. The big disadvantage is that it makes an implicit COMMIT, which is not always so good. If you don’t mind the COMMIT, this is the best way to make your program fall asleep. Please note that you cannot sleep for 1.5 seconds as the parameter only accepts whole numbers.

If a COMMIT doesn’t suit you, because you have a cursor open for the database or you’re in the middle of a transaction, you can always do this:


DATA: ZTIME LIKE SY-UZEIT.

GET TIME.

ZTIME = SY-UZEIT + 10.

DO.
  GET TIME.
  IF SY-UZEIT >= ZTIME.
     EXIT.
   ENDIF.
ENDDO.

Doing this, though, is not very clever. It’s called active standby and it is the last thing you want to do in a program because it is the same as making it run on a gym treadmill: it gets tired and goes nowhere.

Fortunately there is a healthier alternative that, while not freeing up the process, avoids the ill-fated COMMIT:


CALL FUNCTION 'ENQUE_SLEEP'
    EXPORTING
        seconds    = 10.

Greetings from Abapinho.

Thank you Sweet-Rainb0w for the photo.

On your marks, get set, go!

Ladies and gentlemen, boys and girls, the race is about to begin.

Introduction

The four competitors are as follows. They are 4 internal tables, of different races and creeds, which will fight for the athletics title of speed LOOP. Here they are:

Competitor 1: DATA: LT_ITEM TYPE TABLE
Competitor 2: DATA: LT_ITEM_HASHED TYPE HASHED TABLE
Competitor 3: DATA: LT_ITEM_SORTED TYPE SORTED TABLE
Competitor 4: DATA: LT_ITEM TYPE TABLE + INTO INDEX

Ler o resto do artigo! »


About Abapinho
Abapinho runs on WordPress
Articles (RSS) e Comments (RSS).