Ich habe an vielen Orten gelesen (heck, ich habe auch so selbst geschrieben) , dass die Garbage Collection könnte (theoretisch) schneller als die manuelle Speicherverwaltung.
Es ist jedoch viel schwieriger, das zu zeigen, als es zu erzählen.
Ich habe eigentlich nie gesehen jedes Stück Code, der diesen Effekt in Aktion zeigt.
Hat jemand Code (oder weiß, wo ich ihn finden kann), der diesen Leistungsvorteil demonstriert?
memory
garbage-collection
Mehrdad
quelle
quelle
Antworten:
Besuchen Sie http://blogs.msdn.com/b/ricom/archive/2005/05/10/416151.aspx und folgen Sie allen Links, um zu sehen, wie Rico Mariani und Raymond Chen (beide sehr kompetente Programmierer bei Microsoft) gegeneinander antreten . Raymond würde den nicht verwalteten verbessern, Rico würde darauf reagieren, indem er das Gleiche bei den verwalteten optimiert.
Mit im Wesentlichen null Optimierungsaufwand begannen die verwalteten Versionen um ein Vielfaches schneller als das Handbuch. Irgendwann schlug das Handbuch die gemanagten, aber nur durch die Optimierung auf ein Niveau, auf das die meisten Programmierer nicht mehr wollen würden. In allen Versionen war die Speichernutzung des Handbuchs deutlich besser als die des verwalteten.
quelle
swap
) nicht so schwierig ist und Sie wahrscheinlich in Bezug auf die Leistung recht einfach dahin bringen würde ...Als Faustregel gilt, dass es keine kostenlosen Mittagessen gibt.
GC nimmt den Kopfschmerzen der manuellen Speicherverwaltung und verringert die Wahrscheinlichkeit, Fehler zu machen. In einigen Situationen ist eine bestimmte GC-Strategie die optimale Lösung für das Problem. In diesem Fall zahlen Sie keine Strafe für die Verwendung. Aber es gibt andere, bei denen andere Lösungen schneller sind. Da Sie immer höhere Abstraktionen von einer niedrigeren Ebene simulieren können, aber nicht umgekehrt, können Sie effektiv beweisen, dass höhere Abstraktionen auf keinen Fall schneller sein können als niedrigere im Allgemeinen.
GC ist ein Spezialfall der manuellen Speicherverwaltung
Es kann eine Menge Arbeit oder mehr Fehler sein, manuell eine bessere Leistung zu erzielen, aber das ist eine andere Geschichte.
quelle
Es ist einfach, eine künstliche Situation zu konstruieren, in der GC unendlich effizienter ist als manuelle Methoden. Stellen Sie einfach sicher, dass es nur eine "Wurzel" für den Garbage Collector gibt und dass alles Garbage ist, sodass der GC-Schritt sofort abgeschlossen ist.
Wenn Sie darüber nachdenken, ist dies das Modell, das beim Sammeln des Speichers verwendet wird, der einem Prozess zugeordnet ist. Der Prozess stirbt, alles, was es an Speicher gibt, ist Müll, wir sind fertig. Selbst in der Praxis ist ein Prozess, der startet, läuft und stirbt und keine Spur hinterlässt, möglicherweise effizienter als ein Prozess, der für immer startet und läuft.
Bei praktischen Programmen, die in Sprachen mit Garbage Collection geschrieben sind, liegt der Vorteil der Garbage Collection nicht in der Geschwindigkeit, sondern in der Korrektheit und Einfachheit.
quelle
abort()
C ++ aufrufen, bevor das Programm beendet wird. Es ist ein sinnloser Vergleich; Sie sammeln nicht einmal Müll, sondern lassen nur den Speicher auslaufen. Man kann nicht sagen, dass die Müllabfuhr schneller (oder langsamer) ist, wenn man nicht zuerst Müll sammelt ...Es sollte berücksichtigt werden, dass GC nicht nur eine Speichermanagementstrategie ist. Es stellt auch Anforderungen an das gesamte Design der Sprache und der Laufzeitumgebung, die Kosten (und Nutzen) verursachen. Beispielsweise muss eine Sprache, die GC unterstützt, in eine Form kompiliert werden, in der Zeiger nicht vor dem Garbage Collector verborgen werden können und die im Allgemeinen nur von sorgfältig verwalteten Systemprimitiven erstellt werden kann. Ein weiterer Gesichtspunkt ist die Schwierigkeit, die Garantien für die Reaktionszeit einzuhalten, da GC einige Schritte auferlegt, die ausgeführt werden müssen, um vollständig zu sein.
Wenn Sie also eine Sprache haben, in der Datenmüll gesammelt wird, und die Geschwindigkeit mit manuell verwaltetem Speicher im selben System vergleichen, müssen Sie den Aufwand für die Unterstützung der Datenmüllsammlung auch dann bezahlen, wenn Sie sie nicht verwenden.
quelle
Schneller ist zweifelhaft. Es kann jedoch ultraschnell, nicht wahrnehmbar oder schneller sein, wenn es von der Hardware unterstützt wird. Es gab schon vor langer Zeit solche Designs für LISP-Maschinen. Man baute den GC in das Speichersubsystem der Hardware ein, so dass die Haupt-CPU nicht wusste, dass es dort war. Wie viele spätere Designs wurde der GC gleichzeitig mit dem Hauptprozessor ausgeführt, ohne dass Pausen erforderlich waren. Ein moderneres Design sind Vega 3-Maschinen von Azul Systems, auf denen Java-Code viel schneller ausgeführt wird als bei JVMs, die speziell entwickelte Prozessoren und einen pausenlosen GC verwenden. Google sie, wenn Sie wissen möchten, wie schnell GC (oder Java) sein kann.
quelle
Ich habe ziemlich viel daran gearbeitet und einige davon hier beschrieben . Ich habe den Böhm-GC in C ++ verglichen, indem ich ihn zugewiesen,
malloc
aber nicht freigegeben, zugewiesen und freigegeben habe,free
und einen in C ++ geschriebenen, benutzerdefinierten Markierungsbereich-GC, der alle mit dem OCaml-Aktien-GC verglichen wurde, auf dem ein listenbasierter n-Königinnen-Löser ausgeführt wird. Die GC von OCaml war in allen Fällen schneller. Die Programme C ++ und OCaml wurden absichtlich so geschrieben, dass dieselben Zuweisungen in derselben Reihenfolge ausgeführt werden.Sie können die Programme natürlich neu schreiben, um das Problem zu lösen, indem Sie nur 64-Bit-Ganzzahlen und keine Zuordnungen verwenden. Obwohl schneller, würde das den Punkt der Übung zunichte machen (was die Leistung eines neuen GC-Algorithmus vorhersagen sollte, an dem ich mit einem in C ++ erstellten Prototyp gearbeitet habe).
Ich habe viele Jahre in der Industrie verbracht, um echten C ++ - Code auf verwaltete Sprachen zu portieren. In fast jedem Einzelfall stellte ich erhebliche Leistungsverbesserungen fest, von denen viele wahrscheinlich auf die manuelle Speicherverwaltung durch GC zurückzuführen waren. Die praktische Einschränkung ist nicht, was mit einem Mikrobenchmark erreicht werden kann, sondern was vor Ablauf einer Frist erreicht werden kann und GC-basierte Sprachen bieten so große Produktivitätsverbesserungen, dass ich nie zurückblickte. Ich benutze immer noch C und C ++ auf eingebetteten Geräten (Mikrocontrollern), aber selbst das ändert sich jetzt.
quelle
List.filter
wie dies bei C ++ der Fall ist. Aber ja, Sie haben mit Sicherheit recht, dass einige RC-Operationen vermieden werden können. Das größte Problem, das ich in der Natur sehe, ist jedoch, dass die Leute nicht die Zeit haben, solche Optimierungen von Hand auf großen industriellen Codebasen durchzuführen.shared_ptr
nur umwandelten , um Parallelitätsfehler zu beheben. Der Code ist viel langsamer, aber jetzt funktioniert er.Ein solches Beispiel weist notwendigerweise ein schlechtes manuelles Speicherzuweisungsschema auf.
Nimm den besten Müllsammler an
GC
. Intern gibt es Methoden, um Speicher zuzuweisen, zu bestimmen, welcher Speicher freigegeben werden kann, und Methoden, um ihn endgültig freizugeben. Zusammen nehmen diese weniger Zeit in Anspruch als alle anderenGC
; einige Zeit wird in den anderen Methoden der verbrachtGC
.Stellen Sie sich nun einen manuellen Zuweiser vor, der denselben Zuweisungsmechanismus wie verwendet
GC
und dessenfree()
Aufruf nur den Speicher freigibt, der nach derselben Methode wie freigegeben werden sollGC
. Es gibt weder eine Scan-Phase noch eine der anderen Methoden. Es dauert notwendigerweise weniger Zeit.quelle
free
Kann auch Chargen sammeln. (Und natürlich ist das Entfernen aller Elemente, die ein Kriterium erfüllen, immer noch O (N), wenn auch nur aufgrund derfree
in einem Batch-Collect-Modus gearbeitet werden könnte, wenn jedem Speicherelement ein Flag zugeordnet wäre, obwohl GC in einigen Situationen immer noch die Nase vorn haben kann. Wenn man M Referenzen hat, die L verschiedene Elemente aus einer Menge von N Dingen identifizieren, ist die Zeit, um jede Referenz, auf die keine Referenz existiert, zu entfernen und den Rest zu konsolidieren, O (M) und nicht O (N). Wenn man M zusätzlichen Platz zur Verfügung hat, kann die Skalierungskonstante ziemlich klein sein. Außerdem erfordert die Kompaktifizierung in einem Nicht-Scan-GC-System ...