Coder Social home page Coder Social logo

micro_bench's Introduction

MicroBench

Gem Version CircleCI

gem install micro_bench

Why ?

Ruby Benchmark module is nice but it uses blocks. We see 2 problems to it :

  • if we want to instrument a snippet of code, it breaks git history,
  • variables declared in the benchmark block cannot be used subsequently.

Let's say you want to output the duration of method_1 from :

foo = method_1
method_2(foo)

With Benchmark, we would write something like :

foo = nil
duration = Benchmark.realtime do
  foo = method_1
end
puts "Method 1 duration : #{duration} seconds"
method_2(foo)

With MicroBench, it will look like this :

MicroBench.start
foo = method_1
puts "Method 1 duration : #{MicroBench.duration} seconds"
method_2(foo)

Project maturity

This has been running in production at Klaxit for some months now, but it is still a young library. API may be subject to breaking changes on MINOR versions (but not on PATCH versions).

Install

gem install micro_bench

or in Bundler:

gem "micro_bench"

Usage

Basic usage

require "micro_bench"

MicroBench.start

MicroBench.duration
# 1.628093000501394

MicroBench.duration
# 2.999483000487089

MicroBench.stop
# true

MicroBench.duration
# 5.4341670004651

MicroBench.duration
# 5.4341670004651

Named benchmarks

require "micro_bench"

MicroBench.start("timer1")

MicroBench.stop("timer1")

MicroBench.duration("timer1")
# 1.628093000501394

Multiple starts

Calling .start multiple times with the same bench_id (or none) will cause a "restart" of the given benchmark.

Thread safety

A benchmark is tied to a thread, ensuring that MicroBench is thread-safe. At the same time, it doesn't allow to share a benchmark between multiple threads.

Methods isolation

A benchmark is tied to its calling method so the following code will output 2 separated durations for method_1 and method_2. This prevent collisions when using MicroBench in a large codebase.

def method_1
  MicroBench.start
  method_2
  # Do something
  MicroBench.stop
  puts "method_1 duration : #{MicroBench.duration}"
end

def method_2
  MicroBench.start
  # Do something
  MicroBench.stop
  puts "method_2 duration : #{MicroBench.duration}"
end

method_1

Configuration

You can configure a bit MicroBench to have an even simpler time using it afterwards. Here's how:

MicroBench.configure do |config|
  config.formatter = ->(duration) { "#{duration.round} seconds" }
end

MicroBench.start
sleep 2
MicroBench.duration == "2 seconds"

There are some default formatters that you can set:

id result description
default 722.327823832 the raw original float, for computation
simple 722.33 rounds to 2 digits
mmss "12:02.328" Easy to understand, lossless and compact
human "12 minutes and 2 seconds" For humans, clutters logs

To use one of those, simply write config.formatter = :simple instead of a lambda.

Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

While still in beta (before 1.0.0), API may be subject to breaking changes on MINOR versions (but not on PATCH versions).

Authors

See the list of contributors who participated in this project.

License

Please see LICENSE

micro_bench's People

Contributors

buonomo avatar ccyrille avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

micro_bench's Issues

micro_bench requires Ruby 2.3+ (fails in Ruby 2.2)

Hi! I just installed micro_bench in Ruby 2.7 and Ruby 2.2 - it works fine in Ruby 2.7 but throws an exception when you try to require it in Ruby 2.2.

The reason is Line 69:

benchmarks[benchmark_key(bench_id)]&.duration

The code uses the &. which was introduced in Ruby 2.3 and therefore doesn't work earlier than that.

The fix would be to change that line to:

        unless benchmarks[benchmark_key(bench_id)].nil?
          benchmarks[benchmark_key(bench_id)].duration
        end

This was a quick check - I need to run the specs again to be sure that nothing breaks :)
The alternative, of course, is to designate that it requires Ruby >= 2.3

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.