Warum benutzt dieser Scala-Code:
%Vor% erzeuge den folgenden Bytecode für bar()
, der ein neues Tuple2
erstellt, übergibt das Tuple2
von foo()
an es und holt dann die Werte heraus?
Liegt das daran, dass der Compiler nicht überprüft, dass der Rückgabewert foo()
s kein Tupel ist?
Wird die JVM die Konstruktion trotzdem optimieren?
Dies scheint gemäß der Spezifikation (in 4.1 Value Declarations und Definitionen - leicht umformatiert für Stackoverflow-Anzeige:
%Vor%Wertdefinitionen können alternativ ein Muster (§8.1) als linke Seite haben. Wenn p ein anderes Muster als ein einfacher Name oder ein Name gefolgt von einem Doppelpunkt und einem Typ ist, wird die Wertdefinition
val p = e
folgendermaßen erweitert:
- Wenn das Muster
p
die Variablenx1, . . . , xn
gebunden hat, won >= 1
: Hier ist$x
ein neuer Name.
Die Tupelerzeugung erfolgt also in der Parser-Phase. Also setzt val (i, s) = (1, "s")
am Ende der Parser-Phase auf:
Dies bei diesem einfachen Test an einer Million Iterationen messen:
%Vor%ergibt
%Vor%und mit -Optimize flag:
%Vor%Es scheint wie eine verpasste Optimierungsmöglichkeit in scalac.
Der relevante Teil des Compilers ist Entfernt # caseClassUnapplyReturnValue , wodurch TreeDSL#SOME
aufgerufen wird, um Code zum Erstellen eines neuen TupleN
Tags und Links scala tuples iterable-unpacking