2015-01-21 6 views
6

I haben eine komplexe Aufgabe, my_object, die ich mitMashalling in Ruby 2.2.0 2.1.5 langsamer als

Marshal.dump Marshal (my_object)

I die Leistung der Zeile 100 ruft gebenchmarkt haben Zeiten in beiden 2.1.5p273 und 2.2.0 und unten sind die Ergebnisse:

2.1.5 
        user  system  total  real 
Marshal Dump 7.310000 0.120000 7.430000 ( 8.988470) 
Marshal Dump 7.520000 0.050000 7.570000 ( 8.210356) 
Marshal Dump 7.610000 0.050000 7.660000 ( 8.432685) 

2.2.0 
        user  system  total  real 
Marshal Dump 26.480000 0.150000 26.630000 (29.591742) 
Marshal Dump 24.100000 0.300000 24.400000 (28.520397) 
Marshal Dump 26.210000 0.210000 26.420000 (29.993412) 

(. ich das Benchmark 3-mal für jede Version, lief gründlich sein)

Wie Sie sehen können, ist es Ich nehme n Überschuss von 3 mal so lang in 2.2.0 gegenüber 2.1.5. Ich habe mich auf Marshal.dump geeinigt, weil ich mit dem Edelstein Ruby-Prof gezeigt habe, dass dies die Linie war, die schlecht funktionierte. aber ich finde keine Möglichkeit, die Methoden zu erhalten, die Marshal.dump selbst im Profiler aufruft.

Edit: meine Antwort mit einem minimalen repro sehen, nach vielen Experimenten gefunden

+1

Für diejenigen, die dies folgen wollen, habe ich es auf eine minimale Repro reduziert, und loggte es hier: https://bugs.ruby-lang.org/issues/10761. Das Problem scheint nicht die Größe, sondern die Komplexität zu sein, da ich ein Objekt mit vielen Ebenen verschachtelter Objekte erstellen musste, um das Problem zu reproduzieren. – davej

+1

Die Art und Weise, wie du das editiert hast, hat die ursprüngliche Frage verschwinden lassen und diese Frage ... nun, es ist keine Frage, es ist im Grunde eine Antwort. Ich denke, das Ganze ist interessant, aber für SO-Standards denke ich, dass es einen Downvote verdient. – iain

+0

@ian: Wirklich? Meine Wahl war die Frage zu verlassen, die niemandem wirklich geholfen hat, oder etwas zu posten, das, wie ich argumentiere, eine ziemlich große Sache ist, oder die ganze Frage zu löschen. Ich habe getan, was ich für die Gemeinschaft am besten fand. Ehrlich gesagt, ist es Kleinlichkeit wie Ihre, die Geeks einen schlechten Ruf gibt. – davej

Antwort

4

Der Quellenort nil ist.

Dies bedeutet, dass es eine C-implementierte Methode ist, und es gibt keinen Ruby-Code mehr, den Sie verfolgen können. Mit anderen Worten, es ist eine atomare/elementare Methode.

Wenn Sie glauben, dass Ihr Ergebnis gültig ist, empfehle ich Ihnen, das als Fehler in Ruby trunk einzustellen. Für die neuesten Versionen von Ruby wurden tatsächlich einige Performance-Probleme gefunden, so dass Ihr Fall nicht ungewöhnlich erscheint.

+0

danke für die Technik und den Vorschlag. Jetzt beginnt die Suche nach einer winzigen reproduzierbaren Version des Problems! – davej

1

Es ist Marshalling Floats, die die Verlangsamung verursacht.

require 'benchmark' 

class ToBeMarshaled 

    def initialize n 
    @a = [] 
    n.times do |i| 
     @a << i.to_f 
    end 
    end 

end 

tbm = ToBeMarshaled.new(10000) 

n = 100 

Benchmark.bm do |x| 
    x.report("Marshal Dump") {for i in 1..n; Marshal.dump(tbm); end} 
end 

Ergebnisse (lief Benchmark 3-mal für jede Ruby-Version):

2.1.5 
        user  system  total  real 
Marshal Dump 0.640000 0.010000 0.650000 ( 0.744080) 
Marshal Dump 0.670000 0.000000 0.670000 ( 0.758597) 
Marshal Dump 0.650000 0.020000 0.670000 ( 0.747583) 

2.2.0 
        user  system  total  real 
Marshal Dump 25.070000 0.220000 25.290000 (27.980023) 
Marshal Dump 24.100000 0.160000 24.260000 (26.633049) 
Marshal Dump 24.440000 0.230000 24.670000 (27.540826) 

~ 35-mal langsamer.

Wenn Sie die ".to_f" take off von diesem Code erhalten Sie:

2.1.5 
        user  system  total  real 
Marshal Dump 0.160000 0.000000 0.160000 ( 0.180247) 
Marshal Dump 0.180000 0.000000 0.180000 ( 0.189485) 
Marshal Dump 0.160000 0.010000 0.170000 ( 0.191304) 

2.2.0 
        user  system  total  real 
Marshal Dump 0.120000 0.010000 0.130000 ( 0.146710) 
Marshal Dump 0.130000 0.010000 0.140000 ( 0.159851) 
Marshal Dump 0.130000 0.000000 0.130000 ( 0.143917) 

2.2.0 Kanten leicht 2.1.5 aus.