2009-08-19 4 views
0

Gibt es einen Mechanismus, um einen zuverlässigen Wert für die Anzahl aktiver Objekte in einer Ruby-Umgebung zu erhalten? Ich habe mehrere Ansätze gefunden, eine Antwort zu produzieren, und in der Regel ähneln sie:Effiziente, zuverlässige Anzahl aktiver Objekte

c = 0 
ObjectSpace.each_object { c += 1 } 

Das unglückliche Problem dabei ist, dass es eine große Anzahl von Fixnum Objekten einfach erstellt tabelliert, nicht einigen offensichtlichen Aufwand für die erwähnen ObjectSpace-Methode selbst

Natürlich könnte man Ergebnisse nach Klassen filtern und einfach Fixnum-Objekte ignorieren, aber das scheint eine unvollkommene Umgehung zu sein, da es Vermutungen über die Funktionsweise von each_object macht.

Ich möchte nur einen Mechanismus finden, um zu bestimmen, wie viel Müll zwischen einem Punkt während des Betriebs und einem anderen erzeugt wird, da der Müllsammler zu Diagnosezwecken abgeschaltet werden kann, um einen genauen Benchmark zu liefern.

+1

Objekte Keine Fixnum Hier entstehen - Fixnums sind gar nicht erstellt, und sie sind nicht wirklich Objekte in der zugrunde liegenden Implementierung. Sie haben eine wörtliche Darstellung als Ints. Versuchen Sie '42.object_id' einzugeben - Sie werden sehen, dass es immer denselben Wert hat. Deshalb sind 'object_id' von normalen Objekten immer gerade - die ungeraden Zahlen werden für Fixnums verwendet. – Chuck

+0

Ich hatte den Eindruck, dass dies der Fall war, scheint aber nicht so zu sein. Es scheint, als ob es eine Reihe von "fixierten" Fixnums gibt, wie 0, 1, 2, etc., aber ab einem bestimmten Punkt werden sie tatsächlich auf Anfrage zugewiesen. Mit + = wird ein neues Objekt unabhängig vom Typ generiert. – tadman

+1

Nein, es gilt für alle Fixnums. Es ist nur so, dass nicht alle Ganzzahlen Fixnums sind. Ab einem bestimmten Punkt werden sie zu Bignums, die tatsächlich auf Nachfrage zugeteilt werden. Und das Verwenden von + = auf einem Fixnum kann kein neues Objekt generieren, da es nicht möglich ist, ein neues Fixnum zu erstellen. Probieren Sie es aus: 'a = 5; b = 4; a + = 1; b + = 2; a.object_id == b.object_id'. Es gibt eine Fixnum für jede Zahl, denn wie gesagt, es hat eine wörtliche Darstellung durch seine 'object_id'. – Chuck

Antwort

2

Ich sehe keine Möglichkeit, es direkt mit Kernel oder GC zu tun. Rails versucht dies beim Benchmarking zu tun - siehe source code for active_support/testing/performance.rb. Leider sieht es so aus, als ob alle diese Methoden einen gepatchten Ruby-Interpreter benötigen.

Die RubyProf-Dokumente könnten auch nützlich sein; Dies ist eine der Methoden, die Rails zu verwenden versucht. Wenn Sie den Patch (nicht sicher, wo diese finden) anwenden sollten Sie nur in der Lage sein zu tun:

RubyProf.measure_allocations; RubyProf::ALLOCATIONS