Wie kann ich die von einer Methode benötigte Zeit und die einzelnen Anweisungen in dieser Methode in Ruby messen? Wenn Sie die folgende Methode sehen, möchte ich die Gesamtzeit messen, die die Methode benötigt, und die Zeit, die für den Datenbankzugriff und den erneuten Zugriff benötigt wird. Ich möchte Benchmark.measure nicht vor jeder Aussage schreiben. Gibt uns der Ruby Interpreter irgendwelche Haken dafür?
def foo
# code to access database
# code to access redis.
end
Sie können das Objekt Time
verwenden. ( Time Docs )
Beispielsweise,
start = Time.now
# code to time
finish = Time.now
diff = finish - start
diff
würde als Gleitkommazahl in Sekunden angegeben.
EDIT: end
ist reserviert.
Der einfachste Weg:
require 'benchmark'
def foo
time = Benchmark.measure {
code to test
}
puts time.real #or save it to logs
end
Beispielausgabe:
2.2.3 :001 > foo
5.230000 0.020000 5.250000 ( 5.274806)
Die Werte sind: CPU-Zeit, Systemzeit, Gesamtzeit und real verstrichene Zeit.
Quelle: Ruby-Dokumente .
require 'benchmark' # Might be necessary.
def foo
Benchmark.bm(20) do |bm| # The 20 is the width of the first column in the output.
bm.report("Access Database:") do
# Code to access database.
end
bm.report("Access Redis:") do
# Code to access redis.
end
end
end
Dadurch wird etwa Folgendes ausgegeben:
user system total real
Access Database: 0.020000 0.000000 0.020000 ( 0.475375)
Access Redis: 0.000000 0.000000 0.000000 ( 0.000037)
<------ 20 -------> # This is where the 20 comes in. NOTE: Not shown in output.
Weitere Informationen finden Sie hier .
Ein zweiter Gedanke, definieren Sie die measure () -Funktion mit Ruby Codeblockargument kann helfen, den Zeitmesscode zu vereinfachen:
def measure(&block)
start = Time.now
block.call
Time.now - start
end
# t1 and t2 is the executing time for the code blocks.
t1 = measure { sleep(1) }
t2 = measure do
sleep(2)
end
Viele der Antworten deuten auf die Verwendung von Time.now
. Aber es lohnt sich zu wissen, dass Time.now
kann wechseln. Systemuhren können driften und werden möglicherweise vom Systemadministrator oder über NTP korrigiert. Es ist Time.now daher möglich, vorwärts oder rückwärts zu springen und Ihrem Benchmarking ungenaue Ergebnisse zu geben.
Eine bessere Lösung ist die Verwendung der monotonen Uhr des Betriebssystems, die sich immer weiterentwickelt. Ruby 2.1 und höher geben Zugriff darauf über:
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
# code to time
finish = Process.clock_gettime(Process::CLOCK_MONOTONIC)
diff = finish - start # gets time is seconds as a float
Sie können mehr Details lesen hier . Sie können auch das beliebte Ruby Projekt Sidekiq sehen, das auf monotone Uhr umgestellt hat.
Schau in das Ruby-prof
Paket, sollte es haben, was Sie brauchen. Es werden riesige Callstacks mit Timings erstellt.
http://Ruby-prof.rubyforge.org/
Es ist möglicherweise zu detailliert. In diesem Fall werden nur größere Abschnitte in Benchmark.measure
könnte ein guter Weg sein.
Im Geiste von wquists Antwort , aber ein bisschen einfacher könnte man es auch so machen:
start = Time.now
# code to time
Time.now - start