Schnellste Möglichkeit, über einen Stapel in c # zu iterieren

7

Ich finde, dass die Verwendung von GetEnumerator () und das Gießen von IEnumerator.Current teuer ist. Irgendwelche besseren Vorschläge?

Ich bin offen für die Verwendung einer anderen Datenstruktur, wenn sie ähnliche Fähigkeiten mit einer besseren Leistung bietet.

Nach dem Gedanken:
Wäre ein generischer Stack eine bessere Idee, so dass die Besetzung nicht notwendig ist?

    
Adam Naylor 31.10.2008, 09:02
quelle

7 Antworten

6

Hast du irgendwelche Benchmarks gemacht, oder sind sie nur Bauchgefühl?

Wenn Sie denken, dass der Großteil der Verarbeitungszeit damit verbracht wird, durch Stapel zu laufen, sollten Sie einen Benchmark erstellen und sicherstellen, dass dies der Fall ist. Wenn ja, haben Sie ein paar Optionen.

  1. Ändern Sie den Code so, dass die Schleife nicht erforderlich ist
  2. Finden Sie ein schnelleres Schleifenkonstrukt. (Ich würde Generika empfehlen, auch wenn das nicht so wichtig wäre. Auch hier Benchmarks).

BEARBEITEN:

Beispiele für Schleifen, die möglicherweise nicht erforderlich sind, sind Versuche, Suchvorgänge in einer Liste durchzuführen oder zwei Listen oder Ähnliches abzugleichen. Wenn das Looping sehr lange dauert, sehen Sie, ob es Sinn macht, die Listen in Binärbäume oder Hash-Maps zu setzen. Es könnte eine anfängliche Kosten für die Erstellung von ihnen geben, aber wenn der Code neu entworfen wird, können Sie das zurückbekommen, indem Sie später O (1) Lookups durchführen.

    
Mats Fredriksson 31.10.2008, 09:22
quelle
13

Stack<T> (mit foreach) würde zwar die Besetzung retten, aber tatsächlich das schlecht im großen Schema der Dinge. Wenn Sie Leistungsprobleme haben, bezweifle ich, dass dies der Bereich ist, in dem Sie viel Wert hinzufügen können. Verwenden Sie einen Profiler und konzentrieren Sie sich auf echte Probleme - sonst ist dies zu früh.

Beachten Sie, dass wenn Sie die Daten nur einmal lesen möchten (d. h. Sie sind froh, den Stapel zu konsumieren), kann schneller sein (vermeidet den Overhead eines Enumerators); YMMV.

%Vor%     
Marc Gravell 31.10.2008 09:41
quelle
5

Ja, die Verwendung eines generischen Stacks erspart den Cast.

    
csgero 31.10.2008 09:09
quelle
3

Wenn Sie die Funktionalität eines Stapels benötigen (im Gegensatz zu einer Liste oder einem anderen Sammlertyp), dann verwenden Sie einen generischen Stapel. Dies wird die Dinge etwas beschleunigen, da der Compiler das Casting zur Laufzeit überspringt (weil es zur Kompilierungszeit gar nicht erkannt wird).

%Vor%     
Timothy Khouri 31.10.2008 09:20
quelle
2

das Aufzählen über ein generisches IEnumerable<T> oder IEnumerator<T> erzeugt keinen Cast, wenn die iterierende Variable vom Typ T ist, also wird ja das Generische in den meisten Fällen schneller sein, aber Generics haben einige sehr subtile Probleme, besonders wenn sie mit Werttypen verwendet werden.

Rico Mariani (Microsoft Performance-Architekt) hat einige Beiträge, in denen die Unterschiede und die Grundlagen erläutert werden.

Pop Catalin 31.10.2008 09:21
quelle
1

Was die Geschwindigkeit betrifft, gibt es mehrere Variablen, abhängig vom Kontext. Beispielsweise können Sie in einer automatisch speicherverwalteten Codebasis wie C # Zuweisungsspitzen erhalten, die die Framerate in etwa einem Spiel beeinflussen können. Eine nette Optimierung, die Sie anstelle einer foreach vornehmen können, ist ein Enumerator mit einer while-Schleife:

%Vor%

Was CPU-Benchmarks betrifft, ist dies wahrscheinlich nicht schneller als eine foreach, aber foreach kann unbeabsichtigte Zuweisungsspitzen haben, was letztendlich die Leistung Ihrer Anwendung "verlangsamen" kann.

    
Rob Bennet 28.01.2016 04:30
quelle
0

Eine Alternative zum Erstellen eines Enumerators besteht darin, die ToArray-Methode zu verwenden und anschließend über das Array zu iterieren. Der Stapel-Iterator verursacht einen leichten Overhead, um zu prüfen, ob der Stapel geändert wurde, während die Iteration über das Array schnell erfolgen würde. Allerdings ist natürlich der Aufwand für die Erstellung des Arrays an erster Stelle. Wie Matten sagen, sollten Sie die Alternativen benchmarken.

    
Martin v. Löwis 31.10.2008 09:26
quelle

Tags und Links