2010-03-17 12 views
6

Es hat eine Eigenschaft: Zeichenfolge Code und 10 andere.So optimieren Sie diesen Code

common codes ist eine Liste von Zeichenfolgen (string []) Autos eine Liste von Autos (Car []) filteredListOfCars ist List.

for (int index = 0; index < cars.Length; index++) 
{ 
    Car car = cars[index]; 
    if (commonCodes.Contains(car.Code)) 
    { 
     filteredListOfCars.Add(car); 
    } 
} 

Leider ist dieses Stück Methode zu lang.

Ich habe über 50k Aufzeichnungen

Wie kann ich die Ausführungszeit senken ??

Antwort

16

Jared hat richtig darauf hingewiesen, dass Sie dies mit einer HashSet optimieren können, aber ich möchte auch darauf hinweisen, dass die gesamte Methode unnötig ist, Speicher für die Ausgabeliste verschwenden und den Code weniger klar.

Sie konnten das Verfahren schreiben wie:

var commonCodesLookup = new HashSet<int>(commonCodes); 
var filteredCars = cars.Where(c => commonCodesLookup.Contains(c.Code)); 

Ausführung der filteredCars Filteroperation wird aufgeschoben werden, so dass, wenn die Verbraucher davon nur die ersten 10 Elemente wollen, also durch filteredCars.Take(10) verwendet wird, dann ist dieser Es muss nicht die gesamte Liste (oder irgendeine Liste) erstellt werden.

+0

Die Linq Join-Methode führt die Lookup-Logik für Sie, so dass Sie nicht müssen Spezifiziere das HashSet. cars.Join (commonCodes, auto => auto.Code, code => code, (auto, code) => auto) – DRBlaise

+0

@DRBlaise: Es ist wahr, dass 'Join' eine Hash-Tabelle verwendet, aber es ist auch ein Implementierungsdetail und es ist riskant, sich auf solche Dinge zu verlassen, die sich ändern können (selbst wenn Veränderungen unwahrscheinlich sind). Wenn Sie ein bestimmtes Leistungsniveau garantieren möchten, sollten Sie die Semantik explizit angeben. – Aaronaught

+0

Warum int? neuer Hash ist nicht korrekt ?? – user278618

20

Die einfachste Optimierung besteht darin, commonCodes von string[] in eine schnellere Lookup-Struktur wie Dictionary<string,object> oder HashSet<string> zu konvertieren, wenn Sie .Net 3.5 oder höher verwenden. Dies wird die große O-Komplexität dieser Schleife reduzieren und abhängig von der Größe von commonCodes sollte diese Schleife schneller ausgeführt werden.

+0

+1 für mich zu schlagen, um 30 Sekunden, p – Jake

0

könnten Sie die Linq verwenden Befehl kommen, wie

var filteredListOfCars = cars.Join(commonCodes, c => c.Code, cC => cC, (car, code) => car).ToArray(); 
0

Hier ist eine Alternative zu den Linq-Optionen (die auch gute Ideen): Wenn Sie versuchen, Filterung schnell zu tun, würde ich vorschlagen, unter Ausnutzung von eingebauten Typen. Sie könnten eine DataTable erstellen, die zwei Felder hat, die ID des Autos in Ihrem Array und den Code (Sie können die anderen 10 Dinge hinzufügen, wenn sie auch wichtig sind). Dann können Sie einen DataView um ihn herum erstellen und die Filtereigenschaft von diesem verwenden. Es verwendet intern eine wirklich schnelle Indexierung (B-Bäume, glaube ich), so dass Sie wahrscheinlich seine Leistung nicht manuell übertreffen können, es sei denn, Sie sind ein Algorithmus-Experte, was Sie hier nicht fragen würden. Es hängt davon ab, was Sie tun und wie viel Leistung zählt.

1

Um zu tun, was Sie wollen, würde ich die Linq ToLookup-Methode verwenden, um ein ILookup anstelle eines Wörterbuchs zu erstellen. ToLookup wurde speziell für diese Art von Szenario erstellt. Es ist im Grunde eine indexierte Suche nach Gruppen. Sie möchten Ihre Autos nach Code gruppieren.

var carCodeLookup = cars.ToLookup(car => car.Code); 

Die Schaffung des carCodeLookup würde langsam sein, aber dann können Sie es für schnelles Nachschlagen von Autos auf Code basiert. Um Ihre Liste der Autos zu erhalten, die in Ihrer Liste der gängigen Codes enthalten sind, können Sie schnell nachschlagen.

Dies setzt voraus, dass sich Ihre Liste der Autos nicht sehr oft ändert und es sich um Ihre commonCodes handelt, die zwischen Abfragen dynamisch sind.

0

Es sieht aus, als ob Sie wirklich überprüfen, ob der "Code" üblich ist, nicht das Auto. Sie könnten ein Fliegengewichtsmuster betrachten, bei dem Autos gemeinsame Instanzen von Code-Objekten teilen. Das Codeobjekt kann dann eine IsCommon-Eigenschaft und eine Value-Eigenschaft aufweisen. Sie können dann etwas tun, um die verwendeten Code-Objekte zu aktualisieren, wenn sich die Common-Codes-Liste ändert. Wenn Sie jetzt filtern, müssen Sie nur die IsCommon-Eigenschaft jedes Fahrzeugcodes überprüfen