Como posso medir o tempo gasto por um método e as declarações individuais nesse método em Ruby. Se você vir o método abaixo, quero medir o tempo total gasto pelo método e o tempo gasto para acesso ao banco de dados e acesso ao redis. Não quero escrever Benchmark.measure antes de cada declaração. O intérprete ruby nos dá algum gancho para fazer isso?
def foo
# code to access database
# code to access redis.
end
new Date()
do javascript que o ruby tem, mas não consigo me lembrar da sintaxe correta. deve dar-lhe uma lista decente do googleRespostas:
Você pode usar o
Time
objeto. ( Time Docs )Por exemplo,
start = Time.now # code to time finish = Time.now diff = finish - start
diff
seria em segundos, como um número de ponto flutuante.EDITAR:
end
está reservado.fonte
end
é reservado, então use algum outro nome de variável.Time.now
é afetado por ajustes no relógio do sistema, portanto, é uma prática recomendada usá-loProcess.clock_gettime(Process::CLOCK_MONOTONIC)
. Mas para cálculos aproximados, isso não importa. blog.dnsimple.com/2018/03/elapsed-time-with-ruby-the-right-wayA maneira mais simples:
require 'benchmark' def foo time = Benchmark.measure { code to test } puts time.real #or save it to logs end
Saída de amostra:
2.2.3 :001 > foo 5.230000 0.020000 5.250000 ( 5.274806)
Os valores são: tempo da cpu, tempo do sistema, tempo total e real decorrido.
Fonte: ruby docs .
fonte
Benchmark.realtime { block }
se quiser apenas o tempo realUse
Benchmark
's Relatóriorequire '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
Isso resultará em algo como o seguinte:
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: This is not shown in output.
Mais informações podem ser encontradas aqui .
fonte
Benchmark
classe usa um relógio monotônico, conforme discutido em outras respostas. Veja, por exemplo, o seguinte código-fonte e procure por "def measure" na linha 286: github.com/ruby/ruby/blob/ruby_2_2/lib/benchmark.rbMuitas das respostas sugerem o uso de
Time.now
. Mas vale ficar atento queTime.now
pode mudar. Os relógios do sistema podem variar e podem ser corrigidos pelo administrador do sistema ou via NTP. Portanto, é possível que o Time.now avance ou retroceda e forneça resultados imprecisos ao seu benchmarking.A melhor solução é usar o relógio monotônico do sistema operacional, que está sempre avançando. Ruby 2.1 e superior dão acesso a isso via:
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
Você pode ler mais detalhes aqui . Além disso, você pode ver o popular projeto Ruby, Sidekiq, que mudou para o relógio monotônico .
fonte
Pensando bem, definir a função measure () com o argumento do bloco de código Ruby pode ajudar a simplificar o código de medida de tempo:
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
fonte
benchmark
. Quando você o usa, ele é chamadomeasure
. Por favor, corrija isso.No espírito da resposta do wquist , mas um pouco mais simples, você também pode fazer como a seguir:
start = Time.now # code to time Time.now - start
fonte
Olhe na
ruby-prof
embalagem, deve ter o que você precisa. Isso criará enormes pilhas de chamadas com intervalos.http://ruby-prof.rubyforge.org/
Pode ser muito granular; nesse caso, apenas envolver seções maiores
Benchmark.measure
pode ser uma boa opção.fonte
Outro método para comparar o código automaticamente no console Rails é usando esta gema: https://github.com/igorkasyanchuk/execution_time
você verá informações semelhantes à medida que obtém de solicitações em registros
fonte