2014-01-22 4 views
12

This SO answer beschreibt, wie scala.collection.breakOut verwendet werden kann, zu schaffen verschwenderisch Zwischen Sammlungen zu verhindern. Zum Beispiel, hier schaffen wir ein Zwischen Seq[(String,String)]:scala.collection.breakOut vs Ansichten

val m = List("A", "B", "C").map(x => x -> x).toMap 

Durch breakOut nutzen wir die Schaffung dieser Zwischen Seq verhindern kann:

val m: Map[String,String] = List("A", "B", "C").map(x => x -> x)(breakOut) 

Views solve the same problem und zusätzlich Zugriffselemente lazily:

val m = (List("A", "B", "C").view map (x => x -> x)).toMap 

Ich nehme an, die Erstellung der View Wrapper ist ziemlich billig, so meine Frage ist: Gibt es einen wirklichen Grund, breakOut über View s zu verwenden?

Antwort

11

glaube ich nicht identisch sind views und breakOut.

Eine breakOut ist eine CanBuildFrom Implementierung, die verwendet wird, um Umwandlungsvorgänge zu vereinfachen, indem Zwischenschritte eliminiert werden. ZB von A nach B ohne die Zwischensammlung. A breakOut bedeutet, dass Scala das entsprechende Builder-Objekt auswählen muss, um in einem gegebenen Szenario die maximale Effizienz beim Erstellen neuer Objekte zu erzielen. Mehr Details here.

views beschäftigen sich mit einer anderen Art von Effizienz, der Hauptverkaufsbereich ist: "Keine neuen Objekte mehr". Ansichten speichern Licht Verweise auf Objekte unterschiedliche Nutzungsszenarien zu bewältigen: lazy Zugang usw.

Fazit:

Wenn Sie map auf einem view können Sie immer noch eine Zwischen Sammlung von Referenzen erhalten erstellt, bevor das erwartete Ergebnis erzeugt werden . Sie könnten immer noch eine überlegene Leistung von haben:

collection.view.map(somefn)(breakOut) 

als aus:

collection.view.map(someFn) 
12

Du wirst eine Reise von England nach Frankreich machen.

Mit Blick auf: Sie eine Reihe von Notizen in Ihrem Notebook und Boom nehmen, sobald Sie .force genannt haben() Sie anfangen, dass alle von ihnen: buy a ticket, board on the plane, ....

Mit breakout: Sie verlassen und Boom, du in der Paris Blick auf den Eiffelturm. Du erinnerst dich nicht, wie genau du dort angekommen bist, aber du hast diese Reise tatsächlich gemacht, hast einfach keine Erinnerungen gemacht.

Bad Analogie, aber ich hoffe, dies gibt Ihnen einen Eindruck von dem, was ist der Unterschied zwischen ihnen.

1

Was flavian sagte.

Ein Anwendungsfall für Ansichten ist, Speicher zu sparen. Zum Beispiel hatte, wenn Sie eine Million Zeichen lange Zeichenfolge original und zu verwenden benötigt, eins nach dem anderen, all die Millionen Suffixe dieser Zeichenfolge, können Sie eine Sammlung von

verwenden
val v = original.view 
val suffixes = v.tails 

Blick auf das Original Zeichenfolge.Dann könnten Sie die Suffixe nacheinander durchlaufen, indem Sie suffix.force() verwenden, um sie in Strings innerhalb der Schleife zurück zu konvertieren, so dass nur jeweils einer im Speicher gehalten wird. Natürlich können Sie das Gleiche tun, indem Sie mit einer eigenen Schleife über die Indizes der ursprünglichen Zeichenfolge iterieren, anstatt eine Sammlung von Suffixen zu erstellen. Ein anderer Anwendungsfall ist, wenn die Erstellung der abgeleiteten Objekte teuer ist, Sie sie in einer Sammlung (z. B. als Werte in einer Karte) benötigen, aber Sie nur auf einige zugreifen, und Sie nicht wissen, welche .

Wenn Sie wirklich einen Fall, wo zwischen ihnen Kommissionierung sinnvoll ist, bevorzugen breakout es sei denn, für die Verwendung von Ansicht (wie die oben) ein gutes Argument ist.

  • Ansichten benötigen mehr Code-Änderungen und Pflege als breakout, dass Sie Kraft hinzufügen müssen(), wo nötig. Je nach Kontext wird der Fehler oft erst zur Laufzeit erkannt. Mit breakOut, in der Regel wenn es kompiliert, ist es richtig.
  • In den Fällen, in denen die Ansicht nicht zutrifft, wird breakOut schneller sein, da die Generierung und das Forcen von Ansichten übersprungen werden.
  • Wenn Sie einen Debugger verwenden, können Sie den Sammlungsinhalt überprüfen, den Sie nicht sinnvoll mit einer Sammlung von Ansichten tun können.
Verwandte Themen