Frage

  

Mögliche Duplizieren:
   Ist Rekursion immer schneller als Looping?

Ich wurde zum ersten Mal ernsthaft in C, vor etwa 15 Jahren zum Programm geschult. Mein Arbeitgeber wollte für rechen schwierige Aufgaben hoch Code optimiert. Ich erinnere mich, dass mehr als einmal geraten Rekursion als Schleifen neu zu schreiben, auch bei den teueren Lesbarkeit, um zu vermeiden, „Rekursion Aufwand.“ Wie ich es dann verstand, war Rekursion Aufwand der zusätzliche Aufwand benötigten Daten auf einen Stapel schieben und es später aus Pop.

Jetzt habe ich Code in C, Python, Perl, und manchmal Java, und ich frage mich manchmal über Rekursion. Gibt es etwas, noch durch Umschreiben sie gewonnen werden? Was ist, wenn Sie sind Schwanz Rekursion? Haben moderne Compiler alle diese Fragen strittig gemacht? Sind solche Bedenken irrelevant für interpretierten Sprachen?

War es hilfreich?

Lösung

Rekursion kann zu erheblichen Mehraufwand führen, wenn der Kern der rekursiven Funktion ist weniger rechenintensiv als der Funktion Ein- / Ausstiegscode und die Kosten des Anrufs selbst. Der beste Weg, um herauszufinden, ist einfach zwei Versionen des Codes zu profilieren -. Eine rekursive, und man nicht

Das hieß, wenn Sie Ihre Idee Rekursion zu vermeiden, ist ein stapelartige Struktur machen sich, aufgepasst - es nicht unbedingt schneller sein kann als der einfache rekursive Ansatz. Auch hier Profilierungs ist dein Freund.

Schließlich erinnern, dass Programmierer Zeit als CPU-Zeit teurer ist. Bevor Sie Mikro-optimize Code, ist es wirklich eine gute Idee, um zu sehen, zu messen, wenn es wirklich ein Problem sein.

Andere Tipps

Es ist ernst. Die meisten der I-Codesprachen haben ein echt Kosten zu Funktionsaufrufen (die Compiler für sie im Allgemeinen auch so manchmal tun Endrekursion kann es kein Problem).

Diese Kosten und die Tatsache, dass der Stapel nicht eine unbegrenzte Ressource ist, in der Regel machen ich neige Rekursion für Fälle nur zu verwenden, wo ich weiß, dass es eine Grenze für die Tiefe, es zu gehen.

Zum Beispiel weiß, dass ich eine ausgewogene binäre Baumsuche nur fünfzig Ebene tief für einen Billiarde Einträge gehen. Ich würde aber nicht, verwenden Sie:

def sum1through (n):
    if n == 0 return 0
    return n + sum1through (n-1)

da tun, dass für n von zwanzig Millionen würden für einen Stapel nicht gesund sein.

Das Problem existiert noch. Rekursion nimmt vielen Stapelspeicher, da jedes Mal, wenn eine Methode selbst aufruft, einen Zeiger auf ihn und seinen lokalen Variablen werden wieder erzeugt. Die Anzahl der Funktionsaufrufe während der Rekursion gemacht macht eine O (n) Speichernutzung; im Vergleich zu O (1) eine nicht-rekursiven Funktion wie Schleifen.

Ich glaube nicht, dass die Sprache, die Sie erwähnten erfordert , dass die Plattform / Compiler implementiert Endaufruf Beseitigung . Sie können Sprachen finden, dass tun erfordern diese Optimierung -. Meisten funktionalen Sprachen diese Anforderung haben

Aber eine andere Sache, die Sie beachten müssen, ist, dass Computer Größenordnungen haben sich schneller, als sie vor 15 Jahren waren, so ist es jetzt viel seltener ist dann vor, dass Sie über Mikro-Optimierungen zu kümmern. Ein Programm, das 15 Jahre haben vor sorgfältige Hand Optimierung in Assembler ordentliche Leistung erforderlich vielleicht bekommen könnte unglaublich schnell auf einem modernen Computer laufen, auch in einer höheren Sprache wie Java, wenn geschrieben. Das ist nicht, dass die Leistung zu sagen, ist nie ein Problem mehr - aber Sie sollten die auf die Wahl konzentrieren richtigen Algorithmus und auf das Schreiben lesbar Code. Nur Mikro-Optimierungen vornehmen, nachdem Sie die Leistung gemessen haben und Sie können sehen, dass der Code in Frage der Engpass ist.

Eine Sache, die Sie Sie Grund zur Sorge über obwohl fließt über den Stapel. Wenn es ein Risiko, dass das passiert, es könnte sich lohnen, eine rekursive Funktion in einem iterativen Art und Weise Umschreiben statt.

Die Leute sagen viele dumme Dinge über die Leistung.

  1. Wenn Sie Notwendigkeit Rekursion, wie Tiefen ersten Baum zu Fuß zu tun, dann Sie es brauchen, es so verwenden.

  2. Bevor sich Gedanken über die Leistung von alles , herauszufinden, ob Sie ein Problem haben und wo es ist.
    Performance-Probleme sind wie Betrüger und Schwindler - sie sind spezialisiert auf zu sein, wo man es am wenigsten erwarten, so dass, wenn Sie etwas Bestimmtes besorgt sind, wie Rekursion, Sie sind fast garantiert, über die falsche Sache zu sorgen

  3. .

Meiner Meinung nach ist der beste Weg, um Performance-Probleme zu finden, ist durch Stapel Sampling auf Wandtaktzeit und die Proben untersucht, um zu sehen, was das Programm tut, nicht nur durch Messungen erhalten und fragen, was sie bedeuten.

sagte, dass, wenn Sie 10% finden tun oder mehr Zeit in einen rekursiven Aufruf geht, und nicht viel passiert sonst innerhalb der rekursive Routine, und Sie können es Schleife, dann Looping wird es wahrscheinlich Hilfe.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top