C # Lambda-Ausdrucksgeschwindigkeit

8

Ich habe noch nie zuvor viele Lambda-Ausdrücke benutzt und bin auf einen Fall gestoßen, in dem ich dachte, ich könnte es glatt machen. Ich habe eine benutzerdefinierte Liste von ~ 19.000 Datensätze und ich muss herausfinden, ob ein Datensatz existiert oder nicht in der Liste, so anstatt zu schreiben eine Reihe von Schleifen oder Linq verwenden, um durch die Liste zu gehen, entschied ich, dies zu versuchen:

%Vor%

Das einzige Problem ist, dass es ca. 9 - 11 Sekunden dauert. Mache ich etwas falsch, ist das nur ein Fall von wo ich einen Ausdruck wie diesen nicht benutzen sollte?

Danke.

BEARBEITEN: Entschuldigung. Ich sollte es ausarbeiten. Ich erstelle eine Liste von Datensätzen mit der for- und while-Schleife und überprüfe, ob dieser Datensatz in myList existiert. Nur so kann ich darüber nachdenken. Ich werde es neu bewerten und sehen, was ich mit herauf komme.

    
Nathan 09.03.2010, 02:04
quelle

5 Antworten

6

Ihr Algorithmus ist ineffizient. Wenn Sie mehrere Suchen in derselben Liste durchführen, müssen Sie:

  1. Sortieren Sie die Liste entsprechend (nach Ihrem Nachschlageschlüssel).
  2. Verwenden Sie eine binäre Suche , um den richtigen Datensatz zu finden.

Ihre andere Option ist, wenn Speicher kein Problem ist und Sie wollen, dass es wirklich schnell ist, die Datensätze in ein Dictionary<Your_Key,Record> zu setzen. Das gibt Ihnen den schnellsten Zugriff, nachdem Sie es eingerichtet haben.

    
kemiller2002 09.03.2010, 02:11
quelle
12

Dieser Code macht für mich keinen Sinn, deshalb ist es wirklich schwer zu sagen, ob du es falsch machst oder nicht. Quoten sind gut, dass ja, du machst es falsch.

Anstatt den Code anzuzeigen, versuchen Sie es. Angenommen, Sie hätten eine Methode, die genau was Sie wollen. Was wäre die Signatur dieser Methode? Nicht der Körper, nur die Unterschrift.

Angenommen, Sie möchten zum Beispiel die Frage stellen: "Enthält diese Punkteliste einen bestimmten Punkt?" Dann wäre die Signatur

%Vor%

Angenommen, Sie möchten die Frage stellen: "Enthält diese Punkteliste irgendeinen Punkt in diesem Rechteck?" Dann wäre die Signatur

%Vor%

Angenommen, Sie möchten die Frage stellen: "Was haben diese beiden Listen gemeinsam?" dann wäre die Signatur

%Vor%

und so weiter. Geben Sie an, was Sie genauer zu tun versuchen, und wir können Ihnen dabei helfen, diese Operation zu optimieren. Beginnen Sie mit der Unterschrift.

    
Eric Lippert 09.03.2010 02:18
quelle
7

Es ist kein Problem mit dem Lambda, es ist ein Problem mit Ihrem Algorithmus. Sie durchlaufen von MinX zu MaxX, wie viele? dann wiederholst du das gleiche von MinY zu MaxY, dann wiederholst du ~ 19.000 Datensätze. Wenn also die X-Schleife 10 ist und die Y-Schleife 10 ist, dann machen Sie 19.000 * 10 * 10 Anrufe. Es könnte viel schlimmer sein.

    
Joel 09.03.2010 02:08
quelle
2

Wollen Sie das nicht?

%Vor%

Alle resultierenden Elemente erfüllen das Kriterium exists .

... oder habe ich das falsch verstanden?

    
spender 09.03.2010 02:13
quelle
1

Ich werde Kevins Antwort mit einer netten linq-basierten Lösung erweitern.

Der ursprüngliche Code hat effektiv ein zweidimensionales boolesches Array berechnet, das angibt, ob eine Koordinate in myList am x & amp; y -Koordinaten für jedes Array-Element.

Der für jedes x & amp; y kann als Lambda-Funktion als solche ausgedrückt werden:

%Vor%

Dies ist ineffizient, da die Exists -Methode aufgerufen wird und daher die Liste für jede x & amp; y -Koordinate getestet. Ob eine vollständige Liste iteriert wird oder nicht, hängt davon ab, ob eine Übereinstimmung gefunden wird oder nicht. In vielen Fällen gibt es keine Übereinstimmung, daher wird die gesamte Liste mehrmals besucht.

Es ist daher am besten, ein Lexikon von Wörterbüchern vorzuberechnen, um zu bestimmen, ob eine Koordinate in myList für irgendeine x & amp; y Koordinate.

%Vor%

xyLookup erlaubt jetzt die folgende Lambda-Funktion, die ursprüngliche Version zu ersetzen.

%Vor%

Die Vorberechnung von xyLookup benötigt etwas Zeit. Wenn ich ein 3x3-Array habe und myList 3 Koordinaten enthält, haben beide Methoden ungefähr die gleiche Geschwindigkeit. Ich würde jedoch erwarten, dass die tatsächliche Array-Größe und Anzahl der Elemente in myList in der Praxis viel größer wäre.

Wenn ich ein 100x100 Array mit 10.000 Koordinaten in myList habe, dann ist xyLookup ungefähr 91 mal schneller als die ursprüngliche Methode.

Ich liebe linq ...: -)

    
Enigmativity 10.03.2010 01:05
quelle

Tags und Links