Measure user time or system time in Ruby without Benchmark or time
I re-read the Benchmark documentation and saw that it has a method named measure
. This method does exactly what I want: Measure the time your code needs and returning an object which contains user time, system time, system time of childrens etc. It is as easy as
require 'benchmark'
measurement = Benchmark.measure do
# your code goes here
end
In the process I found out that you can add custom rows to the Benchmark output. You can use this to get the best of both worlds (custom time measurements and a nice output at the end) as follows:
require 'benchmark'
measurements = []
10.times { measurements << Benchmark.measure { 1_000_000.times { a = "1" } } }
# measurements.sum or measurements.inject(0){...} does not work, since the
# array contains Benchmark instances, which cannot be coerced into Fixnum's
# Array#sum will work if you are using Rails
sum = measurements.inject(nil) { |sum, t| sum.nil? ? sum = t : sum += t }
avg = sum / measurements.size
# 7 is the width reserved for the description "sum:" and "avg:"
Benchmark.bm(7, "sum:", "avg:") do |b|
[sum, avg]
end
The result will look like the following:
user system total real
sum: 2.700000 0.000000 2.700000 ( 2.706234)
avg: 0.270000 0.000000 0.270000 ( 0.270623)
Ruby on Rails' Method Benchmark Performance
You can use ruby benchmark module for this kind of test
require 'benchmark'
Benchmark.bm do |x|
x.report { User.count }
x.report { u = User.where(account_id: 5); u.count }
x.report { u = User.where(account_id: 5); u.map |a| a.account_id = 6 end }
end
What is an idiomatic way to measure time in Ruby?
A really idiomatic way would be to use the standard library. :)
require 'benchmark'
result = nil
elapsed = Benchmark.realtime do
result = do_something
end
Ruby Benchmarking a line that runs multiple times
There are many gems that might help depending on your application but you could try some of these:
https://github.com/flyerhzm/bullet
https://github.com/SamSaffron/memory_profiler
https://github.com/MiniProfiler/rack-mini-profiler
https://github.com/tmm1/stackprof
https://github.com/oozou/ruby-prof-flamegraph
Another crude approach might be to add a Logger
and log before and after any line which you suspect might be time consuming.
Let's use ruby-prof-flamegraph
example:
Install the gem:
gem install ruby-prof-flamegraph
And the example implementation:
#example.rb
require 'ruby-prof'
require 'ruby-prof-flamegraph'
rubyprof_dir = Gem::Specification.find_by_name('ruby-prof').gem_dir
require "#{rubyprof_dir}/test/prime"
# Profile the code
result = RubyProf.profile do
run_primes(200)
end
# Print a graph profile to text
printer = RubyProf::FlameGraphPrinter.new(result)
printer.print(STDOUT, {})
To generate the image:
bundle exec ruby example.rb | \
~/GitHub/FlameGraph/flamegraph.pl --countname=ms --width=728 > example.svg
Related Topics
How to Specify Local .Gem Files in My Gemfile
Rake VS. Thor for Automation Scripts
Ruby - Using Class_Eval to Define Methods
Finding Nil Has_One Associations in Where Query
Ruby: How to Define a Class Method in a Module
In Rails 4.1, How to Find Records by Enum Symbol
How to Create a Delete Link for a Related Object in Ruby on Rails
Stream Console Output Through Http (With Ruby)
Ruby on Rails Gem for Google Map Integration
Good Cucumber Examples in the Wild
How to Handle Constants in Ruby When Using Rails
Generating Unique, Hard-To-Guess "Coupon" Codes
Rails: How to Access Restful Helpers
Rails: How to Make Date Strftime Aware of the Default Locale
How to Find the Path a Ruby Gem Is Installed at (I.E. Gem.Lib_Path C.F. Gem.Bin_Path)