Seq.map schneller als eine normale for-Schleife?

8

Ich lerne F # und eine Sache, die mich in Bezug auf diese Sprache beschäftigt, ist Leistung. Ich habe einen kleinen Benchmark geschrieben, in dem ich idiomatische F # mit imperativem Code, der in derselben Sprache geschrieben ist, vergleiche - und zu meiner Überraschung kommt die funktionale Version wesentlich schneller heraus.

Der Benchmark besteht aus:

  1. Einlesen einer Textdatei mit File.ReadAllLines
  2. Umkehr der Reihenfolge der Zeichen innerhalb jeder Zeile
  3. Zurückschreiben des Ergebnisses in dieselbe Datei mit File.WriteAllLines.

Hier ist der Code:

%Vor%

Unabhängig von der Dateigröße ist die "F # -Stil" -Version in etwa 75% der Zeit der "C # -Stil" -Version abgeschlossen. Meine Frage ist, warum ist das? Ich sehe keine offensichtliche Ineffizienz in der imperativen Version.

    
Asik 06.05.2012, 05:41
quelle

2 Antworten

10

Seq.map unterscheidet sich von Array.map . Da Sequenzen ( IEnumerable<T> ) erst beim Aufzählen ausgewertet werden, findet im F # -Stil keine Berechnung statt, bis File.WriteAllLines durch die von Seq.map erzeugte Sequenz (nicht Array) läuft.

Mit anderen Worten, Ihre C # -Stil-Version kehrt alle Zeichenfolgen um und speichert die umgekehrten Zeichenfolgen in einem Array und führt dann eine Schleife durch das Array durch, um in die Datei zu schreiben. Die F # -Stil-Version kehrt alle Zeichenfolgen um und schreibt sie mehr oder weniger direkt in die Datei. Das bedeutet, dass der C # -Stil dreimal die gesamte Datei durchläuft (in Array lesen, umgekehrtes Array erstellen, Array in Datei schreiben), während der Code im F # -Stil die gesamte Datei nur zweimal durchläuft (in Array lesen, schreiben umgekehrte Zeilen in Datei).

Sie würden die beste Leistung erzielen, wenn Sie File.ReadLines anstelle von File.ReadAllLines kombiniert mit Seq.map verwenden - aber Ihre Ausgabedatei müsste sich von Ihrer Eingabedatei unterscheiden, wie Sie schreiben würden Ausgabe, während noch vom Eingang gelesen wird.

    
Joel Mueller 06.05.2012, 06:28
quelle
1

Das Formular Seq.map hat mehrere Vorteile gegenüber einer regulären Schleife. Es kann die Funktionsreferenz nur einmal vorberechnen; es kann die Variablenzuweisungen vermeiden; und es kann die Eingabesequenzlänge verwenden, um das Ergebnisarray zu präsize.

    
Raymond Hettinger 06.05.2012 05:45
quelle

Tags und Links