Vorbei an Scala-Map als argument an eine Funktion zu viel Zeit kostet
Ich habe ein scala-companion-Objekt mit einer Methode, die annimmt, eine Karte als parameter. Dann geht diese Karte an eine andere Funktion in einem anderen companion-Objekt ohne Veränderungen. Und die eigentliche Methode aufrufen dauert zu viel Zeit, wenn die Methode, die Ausführung ist schnell (habe ich gemessen alles). Wenn ich don ' T-pass-eine Karte (mit null statt) und es wirkt schnell, aber mit der übergabe als argument, die tatsächlichen Aufruf der Methode ist sehr langsam.
Bin ich etwas fehlt, und die Karte wird neu erstellt und nicht nur eine Referenz übergeben wird?
object ContentElementParser {
def parse(node: Node, assets: Map[String, Asset]): Option[ContentElement] = {
//Some logic here
AssetParser.getAsset(subNode, assets) //this call is too slow because of assets map
}
}
object AssetParser {
def getAsset(node: Node, assetMap: Map[String, Asset]): Asset = {
//logic
}
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wird durch Verweis übergeben. Etwas anderes Los ist-du bist die Messung das erste mal, wenn Sie die Karte verwenden, die erfordert einige Klasse be auch (nachfolgende Aufrufe wäre viel schneller), oder Sie tun viel mehr Arbeit, wenn Sie übergeben eine Karte im Gegensatz zu
null
oder Sie sind sehr knapp aus Speicher und Sie sind mess-garbage-collection-Zeit statt.Könnte es kopiert werden, wenn es eine implizite Konvertierung im Rahmen, aber wenn der Typ Signatur ist genau das gleiche in beiden Orten, das wäre nicht ein Problem, da "keine Konvertierung" hat immer Priorität.
Hier ist der bytecode für die
parse
call (mit einemcontent
Methode HinzugefügtAsset
so erzeugt es eineOption[ContentElement]
, und einsub
Methode HinzugefügtNode
zu füllensubNode
):Sehen? Keine Karte kopieren.
aload_2
ist die Karte übergeben wird. Nichts passiert, außer, dass es angetAsset
überinvokevirtual
.-verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails
auf der Kommandozeile, vielleicht?)Also habe ich versucht zu reproduzieren, dies in einem eigenständigen Projekt-und scheiterte, es funktioniert gut. Aber in einem Projekt war es langsam so offensichtlich etwas anderes vor sich ging.
Ich landete refactoring den code und loszuwerden von Objekt zu Objekt fordert. Erstellt eine übliche Klasse, die akzeptiert assetsMap als Konstruktor val und jetzt funktioniert es viel schneller