Dies ist eigentlich ein tiefes Thema, das einige methodische und einige pragmatische Antworten hat. Ich gehe davon aus, dass Sie etwas über die verfügbaren Algorithmen wissen möchten . Wenn Sie wissen möchten, welcher Algorithmus auf einem bestimmten Computer mit bestimmten Eingaben besser funktioniert, messen Sie die Laufzeiten. Wenn Sie die Qualität eines Compilers für einen bestimmten Algorithmus vergleichen möchten, messen Sie die Laufzeiten. Tun Sie es nicht, um etwas über den Algorithmus zu lernen.
Lassen Sie mich zunächst einige Gründe nennen, warum die Verwendung von Laufzeiten keine gute Idee ist.
- Allgemeines
Laufzeiten, die mit einer Sprache und einem Compiler auf einem Computer gemessen werden, haben wenig Bedeutung, wenn Sie eine Komponente ändern. Selbst geringfügig unterschiedliche Implementierungen desselben Algorithmus können unterschiedlich ausgeführt werden, da Sie eine gewisse Compileroptimierung in Einzelfällen auslösen, in den anderen jedoch nicht.
- Vorhersage
Sie haben also einige Laufzeiten für einige Eingaben. Was sagt das über die Laufzeit einer anderen Eingabe aus? Im Allgemeinen nichts.
- Bedeutung
Normalerweise werden Sie nicht alle Eingaben (von einer bestimmten Größe) einem Benchmarking unterziehen, sodass Sie die Möglichkeit zum Vergleichen von Algorithmen sofort einschränken: Hat Ihr Testsatz möglicherweise den schlechtesten und den besten Fall im anderen Algorithmus ausgelöst? Oder Ihre Eingaben waren zu klein, um das Laufzeitverhalten aufzuzeigen .
- Zumessen
Messlaufzeiten und ist nicht trivial. Gibt es eine GEG? Hat es Streit gegeben, dh zählen Sie die Zeit, die der Algorithmus nicht einmal ausgeführt hat? Können Sie genau denselben Maschinenzustand für einen anderen Durchlauf (des anderen Algorithmus) reproduzieren, insbesondere für gleichzeitige Prozesse und Caches? Wie wird mit Speicherlatenz umgegangen?
Ich hoffe, diese haben Sie überzeugt, dass Laufzeiten ein schreckliches Maß für den Vergleich von Algorithmen sind und dass eine allgemeine, abstrakte Methode zur Untersuchung der Laufzeit von Algorithmen erforderlich ist.
Weiter zum zweiten Teil der Frage. Warum verwenden wir Vergleiche oder ähnliche elementare Operationen?
Analytische Nachvollziehbarkeit
Angenommen, Sie möchten eine formale Analyse durchführen, müssen Sie dazu in der Lage sein . Das Zählen einzelner Aussagen ist sehr technisch, manchmal sogar schwierig. manche Leute machen es trotzdem (zB Knuth). Es ist einfacher, nur einige Anweisungen zu zählen, die die Laufzeit dominieren . Aus dem gleichen Grund untersuchen wir oft "nur" (obere Schranken) die Worst-Case-Laufzeit.
Dominanz
Die ausgewählte Operation dominiert die Laufzeit. Das bedeutet nicht, dass es die meiste Laufzeit beiträgt - Vergleiche, z. B. in Quicksort, wenn Ganzzahlen in Wortgröße sortiert werden, sind dies eindeutig nicht. Sie werden jedoch am häufigsten ausgeführt. Wenn Sie sie also zählen, bestimmen Sie, wie oft die am häufigsten ausgeführten Teile des Algorithmus ausgeführt werden. Folglich ist Ihre asymptotische Laufzeit proportional zur Anzahl der dominanten Elementaroperationen. Aus diesem Grund verwenden wir gerne die Landau-Notation und das Wort "Laufzeit", obwohl wir nur Vergleiche zählen.
Beachten Sie, dass es nützlich sein kann, mehr als eine Operation zu zählen. Zum Beispiel führen einige Quicksort-Varianten mehr Vergleiche durch, aber weniger Swaps als andere (im Durchschnitt).
Wenn Sie die gesamte Theorie durchgearbeitet haben, möchten Sie möglicherweise die Laufzeiten erneut überprüfen, um sicherzustellen, dass die in Ihrer Theorie enthaltenen Vorhersagen stichhaltig sind. Wenn dies nicht der Fall ist, ist Ihre Theorie (in der Praxis) nicht nützlich und muss erweitert werden. Die Speicherhierarchie ist eines der ersten Dinge, die Sie für wichtig halten, die jedoch in grundlegenden Analysen fehlen.