2017-12-22 8 views
0

Warum ist dieser Code:Warum die Ordered Collection langsamer auflistet und wie man damit umgeht?

class Cord : IComparable<Cord> 
{ 
    public int X { get; set; } 
    public int Y { get; set; } 

    public int CompareTo(Cordother) 
    { 
      return this.X.CompareTo(other.X); 
    } 
} 


List<Cord> Cords = LoadCords(); 
stopwatch.Start(); 

foreach(var cord in Cords) 
{ 
      // do something 
} 
stopwatch.Stop(); 

mehrmals schneller als dieser Code:

List<Cord> Cords = LoadCords().OrderBy(r=> r.x).ToList(); 
stopwatch.Start(); 

foreach(var cord in Cords) 
{ 
      // do something 
} 

stopwatch.Stop(); 

Um die Leistung meiner Anwendung zu verbessern Ich brauche eine geordnete Sammlung (die Millionen von Datensätzen ist der Umgang). Ich habe auch versucht, SortSet und Sort-Methode auf Listenelement mit der Implementierung IComparable zu verwenden. In jedem Fall dauert die gleiche Iteration auf der geordneten Liste viel länger als auf der unberührten. Warum ist das so und wie kann ich meine sortierte Sammlung so effizient iterieren lassen wie die Basis?

EDIT: Ich messen nur die Zeit der Iteration. Ich bin mir bewusst, dass das Sortieren Zeit für sich selbst benötigt. Die Operation innerhalb der Schleife ist irrelevant.

Es ist buchstäblich wie ich die Zeile mit Sortierung auskommentieren, Iterationszeit wird kleiner. Es sollte nicht und in anderen Benchmarks nicht, aber in meiner aktuellen Anwendung passiert das und ich frage mich, ob jemand vielleicht einen Rat für mich zu diesem Thema haben kann.

+0

Die foreach-Schleife sollte im zweiten Beispiel nicht länger dauern. Ich schätze, die Zeit ist verloren, die Liste zu sortieren. –

+0

Die Iterationsgeschwindigkeit ist eine gleichzeitig. Der Unterschied ist die Listenvorbereitung, und natürlich ist das Sortieren einer Liste langsamer als das Sortieren. Können Sie Ihre Daten nicht sortieren (aus 'LoadCords()'?) –

+2

Sie sagen, dass die geordnete Sammlung langsamer auflistet, aber der einzige Ort in Ihrem Code, der tatsächlich passiert, ist in '.ToList()'. eigentlich * benchmarking? – itsme86

Antwort

0

Verwenden Sie die linq-Abfrage, um die Ergebnisse zuerst zu filtern, anstatt eine Bedingung in der Schleife auszuführen.

var cords = LoadCords().Where(cord => cord.x >2); 
// Now iterate via linq .ForEach/.Select to do something without if condition. 

Und außerdem wie andere vorgeschlagen mit DataTime.Now geben keine genauen Ergebnisse. Verwenden Sie Stoppuhr.

+0

Dies ist irrelevant und die Verwendung von Where before verlangsamt den gesamten Prozess, Stoppuhr gibt das gleiche Ergebnis –

Verwandte Themen