2009-02-15 17 views
7

Ich habe gerade ein C# -Projekt geerbt, das zu langsam läuft und mit der Optimierung beginnen muss. Was ich zuerst machen wollte, ist etwas mehr über Profiling/Optimieren zu lernen, da ich es vorher nicht tun musste. Die Frage ist also, wo fange ich an, welche Bücher/Blogs/Artikel kann ich lesen?Welche Ressourcen kann ich verwenden, um Profilerstellung/Optimierung zu lernen?

Ich kenne die .net Profiler wie ANTS Profiler und so weiter, aber ich habe keine Ahnung, wie man sie effizient verwendet. Ich habe es nicht wirklich benutzt, lass es einfach auf ein paar Beispiel-Apps laufen, um mit der Ausgabe herumzuspielen.

+0

Spielen Sie mit Profilern, wenn Sie wollen, aber um das Problem zu lösen, tun Sie dies: http://StackOverflow.com/Questions/550109/what-are-some-resources-i-can-use-to-learn- Profiling-Optimierung/575417 # 575417 –

Antwort

14

Es gibt zwei Schritte zur Optimierung des Codes.

Zuerst müssen Sie herausfinden, was langsam ist. Das ist Profiling, und wie Sie vielleicht vermuten, wird dafür häufig ein Profiler verwendet. Die meisten Profiler sind im Allgemeinen einfach zu verwenden. Sie führen Ihre Anwendung durch einen Profiler, und wenn es beendet wird, wird der Profiler Ihnen zeigen, wie viel Zeit in jeder Funktion verbracht wurde, exklusive (diese Funktion ohne die in Funktion aufgerufene Zeit zu zählen) sowie inklusiv (Zeit, die darin verbracht wird Funktion, einschließlich untergeordnete Funktionsaufrufe).

Mit anderen Worten, Sie erhalten einen großen Anrufbaum, und Sie müssen nur die großen Zahlen jagen. Normalerweise haben Sie nur sehr wenige Funktionen, die mehr als 10% der Ausführungszeit beanspruchen. Also suchen Sie diese und Sie wissen was zu optimieren.

Beachten Sie, dass ein Profiler weder notwendig, noch notwendigerweise der beste Ansatz ist. Ein bemerkenswert einfacher, aber effektiver Ansatz besteht darin, das Programm einfach in einem Debugger auszuführen und zu einigen quasi-zufälligen Zeiten die Ausführung anzuhalten und den Aufruf-Stack zu betrachten. Tun Sie dies nur ein paar Mal, und Sie haben eine sehr gute Vorstellung davon, wo Ihre Ausführungszeit verbracht wird. @ Mike Dunlavey, der im Rahmen dieser Antwort kommentierte, hat diesen Ansatz an anderer Stelle ausführlich beschrieben.

Aber jetzt, wo Sie wissen, wo die Ausführungszeit ausgegeben wird, kommt der schwierige Teil wie, um den Code zu optimieren.

Natürlich ist der effektivste Ansatz oft der High-Level-Ansatz. Muss das Problem auf diese Weise gelöst werden? Muss es überhaupt gelöst werden?Konnte es im Voraus gelöst und das Ergebnis zwischengespeichert werden, so dass es sofort geliefert werden konnte, wenn der Rest der App es brauchte? Gibt es effizientere Algorithmen zur Lösung des Problems?

Wenn Sie solche High-Level-Optimierungen anwenden können, tun Sie das, sehen Sie, ob diese Leistung ausreichend verbessert, und wenn nicht, Profil erneut.

Früher oder später müssen Sie möglicherweise in weitere Low-Level-Optimierungen eintauchen. Dies ist jedoch ein schwieriges Gebiet. Heutige Computer sind ziemlich komplex, und die Leistung, die Sie von ihnen erhalten, ist nicht einfach. Die Kosten einer Verzweigung oder eines Funktionsaufrufs können je nach Kontext stark variieren. Das Hinzufügen von zwei Zahlen kann irgendwo zwischen 0 und 100 Taktzyklen dauern, abhängig davon, ob beide Werte bereits in den Registern der CPU waren, was zu der Zeit ausgeführt wird, und eine Anzahl anderer Faktoren. Eine Optimierung auf dieser Ebene erfordert also (1) ein gutes Verständnis der Funktionsweise der CPU und (2) viele Experimente und Messungen. Sie können leicht eine Änderung vornehmen, die Sie denken, wird schneller sein, aber Sie müssen sicher sein, also messen Sie die Leistung vor und nach der Änderung.

Es gibt ein paar allgemeine Faustregeln, die oft Führungs Optimierungen helfen:

I/O teuer ist. CPU-Befehle werden in Bruchteilen einer Nanosekunde gemessen. Der RAM-Zugriff liegt in der Größenordnung von einigen zehn bis einigen hundert Nanosekunden. Ein Zugriff auf die Festplatte kann zig Sekunden dauern Milli Sekunden. So oft, I/O wird sein, was Ihre Anwendung verlangsamt. Führt Ihre Anwendung wenige große E/A-Lesevorgänge durch (lesen Sie eine 20-MB-Datei in einem großen Chunk) oder unzählige kleine (lesen Sie die Bytes 2.052 bis 2073 aus einer Datei, dann ein paar Bytes aus einer anderen Datei)? Weniger große Lesevorgänge können Ihre E/A um einen Faktor von mehreren Tausend beschleunigen.

Seitenfehler betreffen auch Festplattenzugriffe. In-Memory-Seiten müssen in die Auslagerungsdatei geschoben werden, und ausgelagerte Seiten müssen in den Speicher zurückgelesen werden. Wenn das viel passiert, wird es langsam. Können Sie den Standort Ihrer Daten verbessern, sodass weniger Seiten gleichzeitig benötigt werden? Können Sie einfach mehr RAM für den Host-Computer kaufen, um zu vermeiden, Daten auslagern zu müssen? (In der Regel ist Hardware billig. Das Aktualisieren des Computers ist eine vollkommen gültige Optimierung - aber stellen Sie sicher, dass das Upgrade einen Unterschied macht. Das Lesen von Festplatten wird durch den Kauf eines schnelleren Computers nicht viel schneller. Und wenn alles in RAM passt auf Ihrem alten System hat es keinen Sinn, einen mit 8 mal so viel RAM zu kaufen)

Ihre Datenbank stützt sich auch auf Festplattenzugriffe. Kannst du also mehr Daten im RAM zwischenspeichern und nur gelegentlich in die Datenbank schreiben? (Natürlich gibt es ein Risiko dort. Was passiert, wenn die Anwendung abstürzt?

Und dann gibt es jeden Liebling, Threading. Eine moderne CPU hat irgendwo von 2 bis 16 CPU-Kernen zur Verfügung. Verwenden Sie sie alle? Würden Sie profitieren sie verwenden? Gibt es lang andauernde Operationen, die asynchron ausgeführt werden können? Die Anwendung startet den Vorgang in einem separaten Thread und kann dann den normalen Betrieb sofort wieder aufnehmen, anstatt zu blockieren, bis der Vorgang abgeschlossen ist

Also im Grunde genommen Verwenden Sie den Profiler, um Ihre Anwendung zu verstehen.Wie verbringen Sie ihre Ausführungszeit, wo wird sie ausgegeben? Ist der Speicherverbrauch ein Problem? Was sind die I/O-Muster (sowohl Festplatten- als auch Netzwerkzugriffe sowie jede andere Art von I/O)? Läuft die CPU ständig leer oder wartet sie auf einige externe Ereignisse wie I/O oder Timer?

Und dann verstehen Sie so viel wie möglich über den Computer, auf dem es läuft. Verstehen Sie, welche Ressourcen verfügbar sind (CPU-Cache, mehrere Kerne) und was jede einzelne für die Leistung bedeutet.

Dies ist alles ziemlich vage, weil die Tricks zur Optimierung eines großen Datenbankservers werden sehr anders als das, was Sie tun würden, um einige große Zahlen-Crunching-Algorithmus zu optimieren.

+1

@jalf: Das ist eine gute Zusammenfassung von Performance-Analyse-als-großes-Thema. Ich sehe es gerne als kleines Thema. Das Abfragen des Aufruf-Stacks (ich mache es manuell) sagt schnell und präzise, ​​wo der Müll ist. –

3

Wenn Sie ANTS (ein sehr guter Profiler) kennen und bereits gekauft haben, gehen Sie bitte auf here für ein kurzes Tutorial, um Sie zum Laufen zu bringen.

4

Ich nehme einen Bachelor-Kurs (ein Thema ist Leistungsanalyse) und der empfohlene Text ist The Art of Computer Systems Performance Analysis: Techniques for Experimental Design, Measurement, Simulation, and Modeling. Es ist eine Art Bibel zu diesem Thema und könnte etwas übertrieben sein.

+0

Overkill ist schön für die schlaflosen Nächte, wo Sie nur etwas trockenen Text auf Performance-Analyse lesen müssen, um Sie für immer gut :) thx – LDomagala

+0

@LDomagala Amen! – Kredns

2

Wenn Sie Visual Studio Team System habe ich vorschlagen, den Profiler enthält verwenden.
Es ist unter "Analyse-> Profiler"
Die Verwendung dieses Profiler ist wirklich einfach. Du kannst einfach reintauchen und sehen, was du daraus machst. Praktische Übungen sind besser als alle Artikel oder Bücher, die Sie darüber lesen werden.

Finden Sie Ihre ersten paar Engpässe ist einfach wie nur ein paar Klicks. Sie zu lösen, ist vielleicht etwas komplizierter, aber wiederum ist die Optimierung von Code nur eine Frage oder Übung und Erfahrung.

1

Gelesen Rico Mariani's blog. Bevor er befördert wurde, war er ein großer Performance-Tuning-Typ für .Net. Die älteren Einträge in seinem Blog haben eine Menge guter Ratschläge. Ich würde ganz nah am Anfang anfangen und dich nach vorne arbeiten.

Das, plus die Artikel, die Sie bereits gefunden haben (vor allem die first one) sollten Sie beginnen.

0

Dies wird Ihnen bei C# nicht viel helfen, aber die OS X Shark-Tools (mit den Entwicklertools von Apple) sind die besten Profiling-Tools, die ich je gesehen habe. Fast Spaß zu benutzen!

Zur Profilerstellung gibt es zwei Möglichkeiten. Zuerst sollten Sie die Software verstehen. Die Datenstrukturen besonders. Beginnen Sie nicht mit der Optimierung, wenn Sie es nicht zuerst verstanden haben.

Zweitens, Sie sollen Maßnahme (was scheint, du bist im Begriff zu tun). Ich bin fast immer von meinem Bauchgefühl in die Irre geführt worden; Orte, die ich als sekundär betrachten würde, sind die Zeitnehmer. Dies bedeutet auch, dass Sie bei der Optimierung immer für eine bestimmte Anzahl von Testfällen optimieren. Die Auswahl solcher Fälle ist wichtig.

1

Es gibt Profilern und Performance-Analyse-Tools, aber während Sie versuchen, einen finden/kaufen/install/lernen, versuchen Sie nur ein Oldtimer Trick ...

Führen Sie die App unter der IDE, und während es träge ist, drücken Sie die Schaltfläche "Pause" und fragen Sie, was es tut, und warum. Der beste Weg, dies zu beantworten, ist das Lesen des Call-Stacks.

Wenn es mehrmals langsamer als es sein sollte, wie 10 mal, bedeutet das, dass es 90% seiner Zeit damit verbringt, etwas unnötiges zu tun, und das ist die Wahrscheinlichkeit, dass Sie es dabei tun werden. Wenn Sie dies mehrmals wiederholen, können Sie Ihren Verdacht so genau bestätigen, wie Sie möchten.

So brauchen Sie keine teure/populäre aber unscharfe Lupe.

Den Grund für die Langsamkeit zu finden, ist nicht der schwierige Teil, und es gibt normalerweise mehrere.

Der schwierige Teil ist, nachdem Sie ein paar "Low-hanging-Früchte" repariert haben, werden Sie wahrscheinlich die Tatsache, dass der Hauptgrund für die Langsamkeit ist Überentwurf konfrontiert.

Viel Glück.

1

Ich habe Profiler zuvor verwendet, sie können hilfreich sein, aber Sie können eine Menge Hilfe nur von der Erstellung einer Singleton Stoppuhr Typklasse und "Klick" erhalten (haben Sie es ausdrucken die Zeit seit dem letzten Klick und was wurde gerade gemacht, die diese Zeit brauchte) vor und nach Methoden, die Sie für problematisch halten könnten.

Wenn Geschwindigkeit ein Problem in der gesamten App ist, sind Sie wahrscheinlich gehen zu können, nicht zu viel zu tun, um es, aber Sie könnten ein paar Änderungen an der Lage sein ...

Suchen Sie nach inneren Schleifen . Dies sind Performance-Tod. Eine innere Schleife kann durch etwas verursacht werden, das so einfach ist wie das Indizieren in eine verknüpfte Liste oder das Einfügen einer Sortierung in eine Array-basierte Liste.(Sobald ich ein Listenfeld hatte, das 10-20 Minuten benötigte, um mit Zehntausenden von Einträgen gefüllt zu werden, obwohl das zu viele Einträge waren, war der schlimmste Teil, dass es sortiert wurde, indem jeder Eintrag in eine Array-Liste eingefügt wurde).

Suchen Sie nach Fällen, in denen Sie lange Operationen auf Tastendruck ausführen. Diese sollten fast immer außerhalb des Hauptthreads erfolgen.

Denken Sie nicht daran, Dinge wie die Anzahl der Klassen oder wie oft sie instanziiert werden, String-Verkettung (außerhalb von Schleifen), Nullen Variablen oder eine der anderen albernen Strategien, die scheinen, wie sie helfen sollten. Ich habe ein paar ausprobiert und habe mich immer blöd gefühlt, als ich die Dinge verlangsamte, weil ich nicht so schlau war wie die Laufzeit bei den meisten Dingen.

1

Ich würde ein paar der verfügbaren Profiling-Tools (kostenlose Testversionen) herunterladen und sie verwenden.

Ich verwendete jetbrains, und es gibt andere. (ants for example, devpartner und a MS one?, atomatedqa, etc) Sie sollten nicht zu viele Probleme haben, sie zu laufen. Sie haben Berichte, die Ihnen viele Informationen geben und Sie können ziemlich schnell lernen, nur die Anwendungen zu verwenden.

Jeder von ihnen wird Ihnen wahrscheinlich helfen und es ist schön, die Versuche zu verwenden. Sie können dann entweder die Entscheidung, das Tool zu kaufen, einfach zurückstellen oder die eine (n) kaufen, die am hilfreichsten/am einfachsten zu verwenden war. Im Allgemeinen sind sie große Zeit sparen und das Geld wert, obwohl einige teuer sein können. (Ich habe eine harte Zeit mit denen am oberen Ende, wenn es sehr gute Werkzeuge für viel weniger Geld gibt)

Sie könnten einige schwerwiegende/große Leistungsprobleme am ersten Tag finden Sie installieren und ausführen. Ich weiß, dass ich es getan habe.

viel Glück.

Laden Sie einfach einige Tools herunter und starten Sie Ihre App.

EDIT:

Wie für Bücher und Lernen - im Grunde der beste Weg, um Probleme mit dem Code zu lernen, ist schlechter Code zu finden. Oftmals sind Inspektionen mit erfahrenen Entwicklern hilfreich.

als Beispiel: Ich denke, Joel einen Artikel zurück schrieb über er so etwas wie

tat

for (int i = 0; i < strlen (einige string); i ++)

, die ziemlich offensichtlich ist Sie werden bei jeder Iteration der Schleife strlen (teuer) nennen.

Sie müssen einen Blick auf den Code werfen, nachdem der Profiler Ihnen sagt, wo die Zeit verbracht wird und sehen, ob der Code leicht mit einfachen Dingen wie diesem behoben werden kann, oder Änderungen im Design vorgenommen werden müssen die Algorithmen.

0

Mit dem Profiler haben Sie bereits den Nagel auf den Kopf getroffen. Sie alle, zumindest alles, was ich benutzt habe, folgen derselben grundlegenden Methodik. Sie wählen die ausführbare Datei aus und führen die Anwendung aus.

Was Sie mit der Ausgabe tun, ist die Methoden zu finden, die die meiste Zeit benötigen. Dies ist nicht alles, aber Sie haben nach einem guten Weg gefragt, wie Sie den Code optimieren können Anfang. ANTS, die du erwähnt hast, werden standardmäßig lange laufende Routinen anzeigen, wie es die meisten, wenn nicht alle anderen tun.

Sie können die Container-Methoden wie Main() ausschließen, es sei denn, Sie haben eine Menge Code (unwahrscheinlich).

Im Allgemeinen finde ich die meisten Abfälle in drei Bereichen:

  1. Loops
  2. Rekursion
  3. Netzwerklatenz

Bereich # 3, für die Datenbank ist in der Regel leicht zu erkennen wenn Sie auch Ihre Datenbank profilieren, wie Sie die Anzahl der Treffer sehen werden. Der beste Weg, um die Netzwerklatenz zu verringern, sei die Datenbank oder nicht (Service-Anrufe zum Beispiel), besteht darin, in Nachrichten statt in CRUD zu kommunizieren. Fragen Sie nicht jede Tabelle nacheinander ab. Unglücklicherweise erfordert die Lösung häufig Einbauteile vieler gemeinsamer Datenschichten.

Rekursion und Schleifen sind sehr ähnliche Probleme. Wenn Sie nach dem Geld bangen wollen, schlagen Sie zuerst die innere Schleife.

In .NET können Sie auch viel über die Optimierung lernen, indem Sie grundlegende IL lernen und die IL Ihrer Anwendungen mithilfe von Tools wie Reflector untersuchen. Ein bisschen Zeitverschwendung, wenn dies nicht der Hauptteil Ihrer Berufsbeschreibung ist oder etwas, das Sie wahrscheinlich für Ihre zukünftige Karriere ausgeben möchten. Ein Feuerwehrmann zu sein zahlt sich gut aus, aber es kann sehr langweilig sein, ein reiner Wartungs-Coder zu sein.

Es gibt nur ein paar Bücher zum Optimieren und Profilieren von .NET-Anwendungen. Derjenige, der sich im Titel optimiert hat. Das Debugging-Buch für .NET hat einige Informationen zum Profiling, aber es ist nicht sehr tief. Es ist ein großartiges Buch, das zur Optimierung gelesen werden sollte, da viele Probleme, die Fehler verursachen, auch in Ihren Optimierungsreisen auftauchen.

Verwandte Themen