Skip to content

Instantly share code, notes, and snippets.

@ramonrails
Last active January 24, 2024 16:35
Show Gist options
  • Save ramonrails/b77f790298a1951b91c88db1205e7249 to your computer and use it in GitHub Desktop.
Save ramonrails/b77f790298a1951b91c88db1205e7249 to your computer and use it in GitHub Desktop.
ruby console benchmarking shortcuts
# frozen_string_literal: true
# queries in the environment must show SQL
#
# ActiveRecord::Base.verbose_query_logs = true
ActiveRecord::Base.logger = Logger.new($stdout) if defined?(ActiveRecord)
#
# Attempts to load the given gem
#
# @param [String] name of the gem to load
#
# @return [Boolean] gem was loaded or not
#
def gem_loaded?(name = nil)
return false if name.nil?
begin
require name
true
rescue LoadError
false
end
end
#
# Benchmark shortcuts for ruby environment
#
# @param [String | Hash] arg optional name or Hash of names->lambdas
# @param [Proc] &block Proc to call
#
def bmbm(arg = nil, &block)
return "Please install or bundle 'benchmark' gem" unless gem_loaded?("benchmark")
if arg.nil?
# bmbm {...}
block ? bmbm_block(&block) : show_usage_guide
else
# A: bmbm { "name1": ->{...}, ...}
# B: bmbm("name") {...}
block ? bmbm_named_block(arg, &block) : bmbm_hash(arg)
end
# show usage instead of exception
rescue
show_usage_guide
end
#
# bmbm with a hash of named blocks
#
# @param [Hash] arg { "name1": ->{...}, ...}
#
# Usage 3: hash of many blocks, each with a name
# bmbm rand: ->{ rand(0..100) }, time: ->{ Time.now }
# bmbm 'rand': ->{ rand(0..100) }, 'time': ->{ Time.now }
# bmbm Numeric.new => ->{ rand(0..100) }, Time.new => ->{ Time.now }
#
# Rehearsal ----------------------------------------
# rand 0.000011 0.000003 0.000014 ( 0.000008)
# time 0.000009 0.000001 0.000010 ( 0.000009)
# ------------------------------- total: 0.000024sec
# user system total real
# rand 0.000015 0.000007 0.000022 ( 0.000009)
# time 0.000020 0.000003 0.000023 ( 0.000017)
#
def bmbm_hash(arg = nil)
return show_usage_guide unless arg&.is_a?(Hash) && !arg.empty?
Benchmark.bmbm do |x|
arg.each do |name, block|
x.report(name.to_s) { block.call } if block&.is_a?(Proc)
end
end
# show usage instead of an exception
rescue
show_usage_guide
end
#
# bmbm with a name and a block
#
# @param [String] arg name of the benchmark
# @param [Proc] &block to call
#
# Usage 2: block with a name
# bmbm("abc") { rand(0..100) }
#
# Rehearsal ----------------------------------------
# rand 0.000012 0.000003 0.000015 ( 0.000010)
# ------------------------------- total: 0.000015sec
# user system total real
# rand 0.000014 0.000003 0.000017 ( 0.000009)
#
def bmbm_named_block(arg = nil, &block)
return show_usage_guide unless !arg.nil? && block&.is_a?(Proc)
Benchmark.bmbm do |x|
x.report(arg.to_s) { block.call }
end
end
#
# bmbm with just a block
#
# @param [Proc] &block to call
#
# Usage 1: just a block
# bmbm { rand(1..100) }
#
# => #<Benchmark::Tms:0x00007fe8119f9218 @label="",
# @real=1.799999881768599e-05, @cstime=0.0, @cutime=0.0,
# @stime=2.0000000000020002e-05, @utime=2.0999999999993246e-05,
# @total=4.100000000001325e-05>
#
def bmbm_block(&block)
return show_usage_guide unless block
Benchmark.bmbm do |x|
x.report { block.call } if block&.is_a?(Proc)
end
end
#
# Show usage on $stdout
#
# @return [String] usage guide
#
def show_usage_guide
usage = %{
# Usage 1: just a block
# bmbm { rand(1..100) }
# Usage 2: block with a name
# bmbm("abc") { rand(0..100) }
# Usage 3: hash of many blocks, each with a name
# bmbm rand: ->{ rand(0..100) }, time: ->{ Time.now }, ...
# bmbm "rand": ->{ rand(0..100) }, "time": ->{ Time.now }, ...
# bmbm Numeric.new => ->{ rand(0..100) }, Time.new => ->{ Time.now }, ...
}
# log when in rails environment
# NOTE:facilitates the output of the tech-stack tools to be chainable
#
return ActiveRecord::Base.logger.info usage if defined?(ActiveRecord)
# STDOUT in ruby environment
puts usage
end
@ramonrails
Copy link
Author

How does it work?

benchmark gem not installed or bundled

irb(main):001> bmbm
=> "Please install or bundle 'benchmark' gem"

benchmark gem installed

ruby environment

 irb
irb(main):001> bmbm

    # Usage 1: just a block
    #   bmbm { rand(1..100) }

    # Usage 2: block with a name
    #   bmbm("abc") { rand(0..100) }

    # Usage 3: hash of many blocks, each with a name
    #   bmbm rand: ->{ rand(0..100) }, time: ->{ Time.now }, ...
    #   bmbm "rand": ->{ rand(0..100) }, "time": ->{ Time.now }, ...
    #   bmbm Numeric.new => ->{ rand(0..100) }, Time.new => ->{ Time.now }, ...

rails environment (sends output to logger)

 rails c
Loading development environment (Rails 7.1.3)

irb(main):001> bmbm
I, [2024-01-24T21:48:02.780643 #26456]  INFO -- : 
    # Usage 1: just a block
    #   bmbm { rand(1..100) }

    # Usage 2: block with a name
    #   bmbm("abc") { rand(0..100) }

    # Usage 3: hash of many blocks, each with a name
    #   bmbm rand: ->{ rand(0..100) }, time: ->{ Time.now }, ...
    #   bmbm "rand": ->{ rand(0..100) }, "time": ->{ Time.now }, ...
    #   bmbm Numeric.new => ->{ rand(0..100) }, Time.new => ->{ Time.now }, ...
  

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment