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.
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 –