Frage

Das System, das ich hier arbeiten wurde vor .net 2.0 geschrieben und nicht über den Nutzen von Generika. Es wurde schließlich auf 2,0 aktualisiert, aber keiner der Code wurde aus Zeitgründen Refactoring. Es gibt eine Reihe von Orten, an denen der Code verwendet ArraysLists etc., die Dinge als Objekte speichern.

Aus Sicht der Leistung, wie wichtig Änderung des Code zur Verwendung von Generika? Ich weiß von einer Perfomance Perspektive, Boxen und Unboxing usw., es ineffizient ist, sondern wie viel von einem Performance-Gewinn werde es wirklich sein, von ihm zu ändern? Sind Generika etwas auf einem Sprung vorwärts Basis zu verwenden, oder es gibt genug von einer Leistungsänderung, dass ein Gewissen Anstrengungen unternommen werden sollten alten Code aktualisieren gemacht werden?

War es hilfreich?

Lösung

Technisch die Leistung von Generika ist, wie Sie sagen, besser. Allerdings, wenn die Leistung enorm wichtig ist und Sie haben bereits in anderen Bereichen optimiert werden Sie wahrscheinlich durch Ihre Zeit an anderer Stelle viel besser Verbesserungen erhalten.

Ich würde vorschlagen:

  • verwenden Generika für die Zukunft.
  • , wenn Sie solide Unit-Tests haben dann Generika Refactoring, wie Sie Code berühren
  • verbringen andermal Refactorings tun / Messung, die die Leistung erheblich verbessern wird (Datenbankaufrufe, Ändern Datenstrukturen, etc.) eher als ein paar Millisekunden hier und da.

Natürlich gibt es andere Gründe als die Leistung zu Generika zu ändern:

  • weniger fehleranfällig, da Sie kompilieren-Zeit von Typen Überprüfung
  • mehr lesbar ist, müssen Sie nicht alle über den Ort zu werfen und es ist offensichtlich, welche Art in einer Sammlung gespeichert
  • , wenn Sie Generika für die Zukunft verwenden, dann ist es sauberer sie überall zu verwenden

Andere Tipps

Hier ist die Resultate, die ich von einem einfachen Parsen eines Strings aus einer 100 KB Datei 100.000 Mal bekam. Die Generic List (Of Char) nahm 612,293 Sekunden 100.000 Mal über die Datei zu gehen. Die Arraylist nahm 2,880.415 Sekunden 100.000 Mal über die Datei zu gehen. Das bedeutet in diesem Szenario (wie Ihre Laufleistung wird variieren) die generische List (Of Char) 4,7-mal schneller ist.

Hier ist der Code, den ich über 100.000 Mal lautete:

Public Sub Run(ByVal strToProcess As String) Implements IPerfStub.Run
    Dim genList As New ArrayList

    For Each ch As Char In strToProcess.ToCharArray
        genList.Add(ch)
    Next

    Dim dummy As New System.Text.StringBuilder()
    For i As Integer = 0 To genList.Count - 1
        dummy.Append(genList(i))
    Next

End Sub

 Public Sub Run(ByVal strToProcess As String) Implements IPerfStub.Run
     Dim genList As New List(Of Char)

     For Each ch As Char In strToProcess.ToCharArray
         genList.Add(ch)
     Next

     Dim dummy As New System.Text.StringBuilder()
     For i As Integer = 0 To genList.Count - 1
         dummy.Append(genList(i))
     Next
 End Sub

Der einzige Weg, um sicher zu wissen ist Ihr Code zum Profil ein Tool wie DotTrace verwendet wird.

http://www.jetbrains.com/profiler/

Es ist möglich, dass die Boxen / Unboxing in Ihrer Anwendung trivial ist, und würde Refactoring nicht wert sein. In Zukunft sollten Sie immer noch als Generika aufgrund der Kompilierung-Typ Sicherheit verwendet wird.

Generics, ob Java oder .NET, sollte für das Design und die Art Sicherheit, nicht für die Leistung verwendet werden. Autoboxing unterscheidet sich von Generika (im Wesentlichen implizite Objekt primitiven Umwandlungen), und wie Sie erwähnt haben, sollten Sie sie nicht anstelle eines primitiven verwenden, wenn es eine Menge von arithmetischen oder anderen Operationen sein, die eine Performance-Einbußen aus der wiederholten verursachen implizite Objekterstellung / Zerstörung.

Insgesamt würde ich vorschlagen, nach vorn mit gehen, und nur dort vorhandenen Code zu aktualisieren, wenn es für die Typsicherheit / Design-Zwecke gereinigt werden muss, nicht die Leistung.

Es hängt davon ab, die beste Antwort ist Ihren Code zu profilieren und sehen. Ich mag AQTime aber eine Reihe von Paketen existieren für diese.

Im Allgemeinen, wenn ein Arraylist ist viel verwendet wird, kann es sich lohnen, auf eine generische Version wechseln. Wirklich obwohl, es ist sehr wahrscheinlich, dass Sie nicht einmal in der Lage sein würden, den Leistungsunterschied zu messen. Boxing und Unboxing sind zusätzliche Schritte, aber moderne Computer sind so schnell, dass es fast keinen Unterschied macht. Als Arraylist wirklich nur ein normales Array mit einem netten Wrapper ist, würden Sie wahrscheinlich viel mehr Leistung sehen gewonnenen bessere Datenstrukturauswahl (ArrayList.Remove ist O (n)!) Als mit der Umstellung auf Generika.

Edit: Outlaw Programmer einen guten Punkt hat, werden Sie noch Boxen und Unboxing mit Generika sein, es passiert einfach implizit. Der gesamte Code um Überprüfung auf Ausnahmen und Nullen aus Gießen und „ist / als“ keywords obwohl ein wenig helfen würde.

Die größten Gewinne, werden Sie in den Wartungsphasen finden. Generika sind viel einfacher, mit und Updates beschäftigen, ohne dass mit Wandlungs- und Guss Problemen zu behandeln. Wenn dieser Code ist, dass Sie immer wieder besuchen, dann mit allen Mitteln die Mühe nehmen. Ist dieser Code, der in den Jahren berührt wurde nicht, würde ich nicht wirklich gestört hat.

Was ist Autoboxing / Unboxing haben mit Generika zu tun? Dies ist nur ein Typ-Sicherheitsproblem. Mit einer nicht-generischen Sammlung, müssen Sie explizit zurückgeworfen auf ein tatsächliche Art des Objekts. Mit Generika, können Sie diesen Schritt überspringen. Ich glaube nicht, dass es ein Unterschied in der Leistung ein Weg ist, oder das andere.

Meine alte Firma tatsächlich dieses Problem betrachtet. Der Ansatz, den wir haben war: wenn es einfach ist es, Refactoring, tun; wenn nicht (das heißt, wird es zu viele Klassen berühren), lassen Sie es für einen späteren Zeitpunkt. Es hängt wirklich davon ab, ob Sie die Zeit haben, es zu tun, oder ob es mehr wichtige Punkte zu Codierung (das heißt Funktionen, die Sie für Kunden umsetzen sollte).

Dann wieder, wenn Sie nicht auf etwas für einen Kunden arbeiten, gehen Sie voran und Zeit Refactoring verbringen. Es wird für sich selbst Lesbarkeit des Codes verbessern.

Abhängig von wie viel ist da draußen in Ihrem Code. Wenn Sie in der Benutzeroberfläche große Listen Bindung oder angezeigt werden, würden Sie wahrscheinlich einen großen Gewinn in der Leistung sehen.

Wenn Ihre Arraylist über nur verstreut ist hier und da, dann wäre es wahrscheinlich keine große Sache sei es nur, um aufgeräumt, aber auch nicht die Gesamtleistung sehr viel auswirken würde.

Wenn Sie eine Menge ein Arraylisten im gesamten Code verwenden, und es wäre ein großer untertaking sein, sie zu ersetzen (etwas, das Ihre Zeitplan auswirken kann), dann könnte man annimmt einen if-you-Touch-it-Wechsel-it-Ansatz .

Hauptsache ist aber, dass Generics viel einfacher zu lesen ist, und ist stabiler über die App aufgrund der starken Typisierung Sie von ihnen erhalten. Sie werden Gewinne sehen nicht nur von Leistung, sondern von Code maintainablity und Stabilität. Wenn Sie es schnell tun können, würde ich sagen, es zu tun.

Wenn Sie kaufen-in aus dem Product Owner zu bekommen, würde ich empfehlen, es immer aufgeräumt. Sie lieben Ihren Code mehr danach.

Wenn die Einheiten in den Arraylisten Objekttypen sind, werden gewinnen Sie ein wenig von ihnen nicht auf die richtige Art zu werfen. Wenn sie Werttypen (structs oder Primitiven, wie Int32) sind, dann wird die Box / Unboxing-Prozess fügt eine Menge Aufwand und generische Sammlungen sollten viel schneller sein.

Hier ist ein MSDN-Artikel über das Thema

Generics hat viele bessere Leistung vor allem, wenn Sie Wert-Typ werden mit (int, bool, Struktur etc.), wo Sie einen noticeble Performance-Gewinn gewinnen werden.

  1. Mit Arraylist mit Wert-Typ verursacht Boxen / Unboxing, das, wenn mehrere hundert Mal getan wird im wesentlichen durch langsamer als generische Liste verwendet wird.

  2. bei der Lagerung von Werttypen als Objekt, das Sie werde bis zu vier Zeitspeichern pro Stück. Während dieser Betrag wird Ihr RAM den Cache-Speicher nicht ab, der kleiner ist weniger Elemente enthalten könnte, was bedeutet, dass, während eine lange Sammlungen iterieren es viele Kopien aus dem Hauptspeicher in den Cache sein würde, die Ihre Anwendung verlangsamen würde.

Ich schrieb über hier .

die Verwendung von Generika sollte auch bedeuten, dass der Code einfach sein und einfach zu bedienen, wenn Sie Dinge wie Linq in den späteren c # Versionen nutzen möchten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top