Welche Ressourcen kann ich verwenden, um Profilerstellung / Optimierung zu lernen?

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?

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

    
LDomagala 15.02.2009, 01:18
quelle

11 Antworten

14

Es gibt zwei Schritte zum Optimieren 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 bekommen einen großen Rufbaum, 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 anderswo ausführlich beschrieben.

Aber jetzt, da Sie wissen, wo die Ausführungszeit verbracht wird, kommt der schwierige Teil wie zur Optimierung des Codes.

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 dies, um zu sehen, ob diese Leistung ausreichend verbessert wurde, und wenn nicht, Profil erneut.

Früher oder später müssen Sie möglicherweise in tiefere Optimierungen einsteigen. 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 zwischen 0 und 100 Taktzyklen dauern, abhängig davon, ob sich beide Werte bereits in den Registern der CPU befanden, was else zur Zeit ausgeführt wird und eine Reihe weiterer 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 helfen, Optimierungen zu führen:

I / O ist teuer. CPU-Befehle werden in Bruchteilen einer Nanosekunde gemessen. Der RAM-Zugriff liegt in der Größenordnung von einigen zehn bis einigen hundert Nanosekunden. Ein Festplattenzugriff kann einige zehn Millisekunden dauern. 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 und lesen Sie 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.

PageFaults 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 ist auch auf Festplattenzugriffe angewiesen. Kannst du also mehr Daten im RAM zwischenspeichern und nur gelegentlich in die Datenbank schreiben? (Natürlich besteht dort ein Risiko. Was passiert, wenn die Anwendung abstürzt?

Und dann ist da jeder Favorit, Threading. Eine moderne CPU verfügt über 2 bis 16 CPU-Kerne. Benutzt du sie alle? Würdest du davon profitieren? 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.

Im Grunde genommen sollten Sie den Profiler verwenden, um Ihre Anwendung zu verstehen. Wie verbringt es seine Ausführungszeit, wo wird es ausgegeben? Ist der Speicherverbrauch ein Problem? Was sind die E / A-Muster (sowohl Festplatten- und Netzwerkzugriffe als auch jede andere Art von E / A)?Läuft die CPU ständig oder ist sie im Leerlauf und wartet auf externe Ereignisse wie I / O oder Timer?

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

Das ist alles ziemlich vage, denn die Tricks zur Optimierung eines großen Datenbankservers werden sehr sein, anders als das, was Sie tun würden, um einen großen Algorithmus zur Zahlenverarbeitung zu optimieren.

    
jalf 21.02.2009, 21:21
quelle
4

Ich nehme einen Bachelor-Kurs (ein Thema ist Performance Analysis) und der empfohlene Text ist Die Kunst der Computer-System-Performance Analyse: Techniken für experimentelles Design, Messung, Simulation und Modellierung . Es ist etwas von einer Bibel zu diesem Thema und könnte ein bisschen übertrieben sein.

    
vinc456 15.02.2009 01:29
quelle
3

Wenn Sie ANTS (einen sehr guten Profiler) kennen und bereits gekauft haben, gehen Sie hier für ein schnelles Tutorial, um Sie zum Laufen zu bringen.

    
Andrew Hare 15.02.2009 01:20
quelle
2

Wenn Sie Visual Studio Team System haben, schlage ich vor, den enthaltenen Profiler zu verwenden.
Es befindet sich unter "Analyse- & Profiler" Die Verwendung dieses Profilers ist wirklich einfach. Du kannst einfach reintauchen und sehen, was du daraus machst. Praktische Übungen sind besser als alle Artikel oder Bücher, die du darüber lesen wirst.

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

    
shoosh 21.02.2009 21:18
quelle
1

Lesen Sie Rico Marianis 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 (besonders die erste ) sollten mach dich bereit.

    
Sean Reilly 22.02.2009 16:28
quelle
1

Es gibt Profiler und Leistungsanalyse-Tools, aber während du versuchst, einen zu finden / zu kaufen / zu installieren / zu lernen, probiere einfach einen Trick des alten Tigers aus ...

Führen Sie die App unter der IDE aus, und während es schwerfällig ist, klicken Sie auf die Schaltfläche "Pause" und fragen Sie, was es macht und warum . Der beste Weg, dies zu beantworten, ist durch Lesen der Aufrufliste.

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

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

Es ist also nicht schwer, den Grund für die Langsamkeit zu finden, und es gibt gewöhnlich mehrere.

Der schwierige Teil ist, nachdem Sie ein paar "Low-hanging-fruits" repariert haben, werden Sie wahrscheinlich der Tatsache gegenüberstehen müssen, dass der Hauptgrund für die Langsamkeit ein Überdesign ist.

Viel Glück.

    
Mike Dunlavey 22.02.2009 18:37
quelle
1

Ich habe früher Profiler verwendet, sie können hilfreich sein, aber Sie können eine Menge Hilfe bekommen, indem Sie einfach eine Singleton-Stoppuhr-Klasse erstellen und sie "anklicken" (die Zeit seit dem letzten Klick ausgeben und was war) gerade getan, dass diese Zeit) vor und nach Methoden, die Sie denken, könnte problematisch sein.

Wenn die Geschwindigkeit in der ganzen App ein Problem ist, werden Sie wahrscheinlich nicht viel tun können, aber Sie könnten vielleicht ein paar Änderungen vornehmen ...

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.) p>

Suchen Sie nach Fällen, in denen lange Operationen auf der Basis von Tastendrucken ausgeführt werden. Diese sollten fast immer außerhalb des Hauptthreads erfolgen.

Denken Sie nicht einmal daran, Dinge wie die Anzahl der Klassen oder wie oft sie instanziiert werden, String-Verkettungen (außerhalb von Schleifen), Variablen auszuwerten oder andere alberne Strategien, die scheinbar 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.

    
Bill K 24.02.2009 00:16
quelle
1

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

Ich habe jetbrains verwendet, und es gibt noch andere. ( Ameisen zum Beispiel , devpartner und ein MS eins? , atomatedqa , etc) Sie sollten nicht habe zu viele Probleme, sie auszuführen. Sie haben Berichte, die Ihnen viele Informationen geben und Sie können ziemlich schnell lernen, wenn Sie nur die Anwendungen verwenden.

Jeder von ihnen wird dir wahrscheinlich helfen und es ist schön, die Versuche zu benutzen. 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)

Am ersten Tag der Installation und Ausführung können einige schwerwiegende / schwerwiegende Leistungsprobleme auftreten. Ich weiß, dass ich es getan habe.

viel Glück.

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

BEARBEITEN:

Was Bücher und Lernen betrifft - im Grunde genommen ist der beste Weg, über Probleme mit Code zu lernen, schlechter Code zu finden. Oftmals sind Inspektionen mit erfahrenen Entwicklern hilfreich.

als ein Beispiel: Ich glaube, Joel hat einen Artikel geschrieben, der zurückgeht, dass er so etwas wie

gemacht hat

für (int i = 0; i & lt; strlen (irgendeine Zeichenkette); i ++)

das ist ziemlich offensichtlich, dass Sie strlen (teuer) jede Iteration der Schleife nennen werden.

Sie müssen sich einen Teil des Codes ansehen, 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 des gemacht werden müssen Algorithmen.

    
Tim 25.02.2009 22:54
quelle
1

diese zwei Artikel sind alles, was ich bis jetzt gefunden habe:

Finden Sie Anwendungsengpässe mit Visual Studio Profiler

Messen der .NET-Anwendungsleistung

    
LDomagala 15.02.2009 15:17
quelle
0

Das 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!

Für die Profilerstellung gibt es zwei Möglichkeiten. Zuerst sollten Sie die Software verstehen . Die Datenstrukturen besonders. Beginne nicht zu optimieren, es sei denn, du verstehst es zuerst.

Zweitens sollten Sie messen (was Ihnen bevorzustehen scheint). 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.

    
akauppi 22.02.2009 16:50
quelle
0

Sie haben mit dem Profiler 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 dann die Anwendung aus.

Was Sie mit der Ausgabe machen, ist, die Methoden zu finden, die am meisten Zeit beanspruchen. Dies ist nicht alles, aber Sie haben nach einem guten Weg gefragt, wie Sie Code optimieren können. Daher sind die lang laufenden Routinen ein guter Anfang . ANTS, das Sie erwähnt haben, wird 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 sehr viel Code (unwahrscheinlich).

Im Allgemeinen finde ich die meiste Verschwendung in drei Bereichen:

  1. Schleifen
  2. Rekursion
  3. Netzwerklatenz

Bereich # 3 für die Datenbank ist im Allgemeinen leicht zu erkennen, wenn Sie auch Ihre Datenbank profilieren, da Sie die Anzahl der Treffer sehen. 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 suchen, drücken Sie zuerst die innere Schleife.

In .NET können Sie auch viel über 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 zahlt sich gut aus, aber es kann sehr langweilig sein, einen reinen Wartungs-Coder zu haben.

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 muss, da viele Probleme, die Fehler verursachen, auch in Ihren Optimierungsreisen auftauchen.

    
Gregory A Beamer 26.02.2009 19:47
quelle

Tags und Links