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:
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
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)
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.
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… 😉
- Komplexe Datenobjekte editieren - 23. Januar 2023
- Einfügen von vielen Daten in Tabellenpflegedialog - 14. November 2022
- SALV-Table-Popup als Suchhilfe - 14. Oktober 2022