Ich versuche, etwas mehr über LINQ zu lernen, indem ich Peter Norvigs Rechtschreibkorrektor in C # implementiere.
> Der erste Teil beinhaltet eine große Wortdatei (etwa 1 Million) und legt sie in ein Wörterbuch, in dem% co_de steht % ist das Wort und key
ist die Anzahl der Vorkommen.
Ich würde das normalerweise so machen:
%Vor% Wo value
ein allWords
In LINQ mache ich das momentan so:
%Vor% Ich vergleiche die 2 Wörterbücher, indem ich mir alle IEnumerable<string>
anschaue und sie sind identisch, so dass sie die gleichen Ergebnisse liefern.
Die Schleife <key, value>
dauert 3,82 Sekunden und die LINQ-Abfrage dauert 4,49 Sekunden
Ich benutze die Stopwatch-Klasse und fahre im RELEASE-Modus. Ich denke nicht, dass die Leistung schlecht ist. Ich habe mich nur gefragt, ob es einen Grund für den Unterschied gibt.
Mache ich die LINQ-Abfrage auf eine ineffiziente Weise oder fehle ich etwas?
Update: Hier ist das vollständige Benchmark-Codebeispiel:
%Vor%Einer der Gründe, warum die LINQ-Version langsamer ist, besteht darin, dass anstelle eines Wörterbuchs zwei Wörterbücher erstellt werden:
(intern) von der Gruppe nach Betreiber; Die Gruppe durch speichert auch jedes einzelne Wort. Sie können dies überprüfen, indem Sie ein ToArray () und nicht ein Count () betrachten. Dies ist eine Menge Overhead, die Sie in Ihrem Fall eigentlich nicht brauchen.
Die ToDictionary-Methode ist im Grunde eine Foreach-Abfrage über die eigentliche LINQ-Abfrage, bei der die Ergebnisse der Abfrage einem neuen Wörterbuch hinzugefügt werden. Je nach Anzahl der eindeutigen Wörter kann dies auch etwas dauern.
Ein weiterer Grund dafür, dass die LINQ-Abfrage ein wenig langsamer ist, ist, dass LINQ auf Lambda-Ausdrücken basiert (der Delegat in Dathans Antwort), und das Aufrufen eines Delegaten einen kleinen Mehraufwand im Vergleich zu Inline-Code erfordert.
Bearbeiten: Beachten Sie, dass bei einigen LINQ-Szenarios (wie LINQ to SQL, aber nicht LINQ im Arbeitsspeicher wie hier) das Neuschreiben der Abfrage zu einem optimierten Plan führt:
%Vor%Beachten Sie jedoch, dass Sie damit kein Wörterbuch erhalten, sondern eine Folge von Wörtern und deren Anzahl. Sie können dies in ein Dictionary mit
umwandeln %Vor%Indem ich LINQ komplett missbrauchte, konnte ich erreichen, dass es ungefähr gleich und oft etwas schneller war als die foreach-Schleife, sogar mit einem Delegat-Aufruf:
%Vor% Selbst wenn foreach
so geändert wurde, dass ein ähnlicher Satzausdruck verwendet wurde, wurde es nicht schneller.
Tags und Links .net linq performance foreach