Exporting vs. Returning. Gibt es da Unterschiede?

Ein Kollege ist kürzlich bei der Überarbeitung seines Programmes über eine Meldung aus dem Code Inspector gestolpert:

==> Der Typ des RETURNING-Parameters „RETURN_VALUE“ enthält eine oder mehrere Strings (Siehe Test-Dokumentation).

Die Meldung hat verwundert, da die Übergabe eines Strings als RETURNING-Parameter eigentlich nichts „Böses“ ist. Die Erklärung der Meldung ist jedoch einleuchtend:

Inperformante Parameterübergabe

Bei der Parameter-Übergabe in ABAP gibt es die Modi Referenz-Übergabe (keine oder Kennzeichnung reference(PARAM)) und Wert-Übergabe (Kennzeichnung value(PARAM) ). Es gilt allgemein die Regel, dass Wert-Übergabe immer langsamer als Referenz-Übergabe ist. Der Performance-Nachteil ist immer mindestens 40 % und kann abhängig vom Datentyp und Datenvolumen auf mehrere 1000 % Prozent steigen.

STR: Der Typ des VALUE-Parameters enthält keine Tabellen aber Strings. In diesem Fall findet bei Parameter-Übergabe ein String-Sharing statt, was aber relativ aufwändig ist. Der Performance-Nachteil gegenüber Referenz-Übergabe beträgt hier bei ca. 700 %. Dieser Wert gilt nur für den Fall dass der Parameter nicht geändert wird. Erfolgt eine Änderung steigt dieser Wert noch weiter an.

Rückgabe-Parameter (RETURNING)

Da RETURNING-Parameter immer VALUE-Parameter sind, ist hier eine Performance-Verbesserung nur durch Änderung der Parameter-Art möglich. Der RETURNING-Value-Parameter muss in einen EXPORTING-Reference-Parameter umgewandelt werden.

String-Sharing

Die Erklärung des Code Inspectors scheint schlüssig. Mit einem Testprogramm wollte ich die Performance-Unterschiede testen. Das Programm verwendet zwei Methoden, die jeweils einen String zurück geben. Vor Ausführung kann festgelegt werden, wie groß der String werden soll (Parameter P_LENTH) und wie oft die Methoden ausgeführt werden sollen (Parameter P_TIMES).

Es ist schnell ersichtlich, dass bei Zunahme der String-Größe die Ausführungszeit tatsächlich signifikant steigt. Bei kurzen Strings (~100 Bytes) ist die RETURNING-Variante etwa 25% langsamer.

Testprogramm <<hier aufklappen>>
REPORT.

PARAMETERS p_times  TYPE i DEFAULT 10000.
PARAMETERS p_length TYPE i DEFAULT 10000.

*----------------------------------------------------------------------*
*       CLASS l DEFINITION
*----------------------------------------------------------------------*
CLASS l DEFINITION.
  PUBLIC SECTION.
    CLASS-DATA teststring TYPE string.
    CLASS-METHODS ret RETURNING value(val) TYPE string.
    CLASS-METHODS imp EXPORTING val TYPE string.
    CLASS-METHODS testdata IMPORTING len TYPE i.
ENDCLASS.                    "l DEFINITION

*----------------------------------------------------------------------*
*       CLASS l IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS l IMPLEMENTATION.
  METHOD testdata.
    DO len TIMES.
      CONCATENATE teststring 'A' INTO teststring.
    ENDDO.
  ENDMETHOD.                    "class_constructor

  METHOD ret.
    val = teststring.
  ENDMETHOD.                    "ret

  METHOD imp.
    val = teststring.
  ENDMETHOD.                    "imp
ENDCLASS.                    "l IMPLEMENTATION

*== data
DATA start TYPE i.
DATA stopp TYPE i.
DATA result TYPE i.
DATA string TYPE string.

START-OF-SELECTION.

  l=>testdata( p_length ).
*== test RETURNING
  GET RUN TIME FIELD start.
  DO p_times TIMES.
    string = l=>ret( ).
  ENDDO.
  GET RUN TIME FIELD stopp.

  result = stopp - start.
  WRITE: / 'Returning', result.

*== Test EXPORTING
  GET RUN TIME FIELD start.
  DO p_times TIMES.
    l=>imp( IMPORTING val = string ).
  ENDDO.
  GET RUN TIME FIELD stopp.

  result = stopp - start.
  WRITE: / 'Exporting', result.

Fazit

Im Normalfall würde ich bei Rückgabe eines String-Feldes immer die RETURNING-Variante wählen, da sie „schöner“ ist. Die direkte Wertübergabe, die RETURNING möglich macht, macht das Coding eleganter und verständlicher. Wenn mit großen Strings gearbeitet wird und diese Verarbeitung zudem sehr oft durchgeführt wird, solltest du dich jedoch an diesen Artikel erinnern… 😉

image_pdfimage_print