micro_bench 0.1.3 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +37 -2
- data/lib/micro_bench.rb +21 -1
- data/lib/micro_bench/benchmark.rb +2 -0
- data/lib/micro_bench/configurations.rb +84 -0
- data/lib/micro_bench/version.rb +3 -1
- data/spec/micro_bench/configurations_spec.rb +30 -0
- data/spec/{micro_bench/micro_bench_spec.rb → micro_bench_spec.rb} +21 -5
- metadata +12 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: e7b61de43614716fc3e48d6661bc4f77524092a7766cd808a5cfdb09e4a70f3b
|
|
4
|
+
data.tar.gz: 25deba16810136e20ba13a28dde5b73a63b57a7e639700582b726f9853f8fe9c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9cdb819b4a60cdc8a7eb958a222217942ff90da5896698af0f2c66b66ed8ccc62f5583241962c0479181aadcf5a098d66505d6a3172dde7246e239d6fffb66f3
|
|
7
|
+
data.tar.gz: 6612a374748347f8858cacf36acfa0b712c0d8c93a86242896203558261eb748d49c303aff25602ec89a0f34f08e2c34a67b8a92955e20e59027bb4fac70e363
|
data/README.md
CHANGED
|
@@ -2,10 +2,17 @@
|
|
|
2
2
|
# MicroBench
|
|
3
3
|
|
|
4
4
|
[](https://badge.fury.io/rb/micro_bench)
|
|
5
|
+
[](https://circleci.com/gh/klaxit/micro_bench)
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
gem install micro_bench
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Why ?
|
|
5
12
|
|
|
6
13
|
Ruby `Benchmark` module is nice but it uses blocks. We see 2 problems to it :
|
|
7
14
|
- if we want to instrument a snippet of code, it breaks git history,
|
|
8
|
-
- variables
|
|
15
|
+
- variables declared in the benchmark block cannot be used subsequently.
|
|
9
16
|
|
|
10
17
|
Let's say you want to output the duration of `method_1` from :
|
|
11
18
|
|
|
@@ -32,7 +39,10 @@ puts "Method 1 duration : #{MicroBench.duration} seconds"
|
|
|
32
39
|
method_2(foo)
|
|
33
40
|
```
|
|
34
41
|
|
|
35
|
-
|
|
42
|
+
## Project maturity
|
|
43
|
+
|
|
44
|
+
This has been running in production at [Klaxit](https://www.klaxit.com) 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).
|
|
45
|
+
|
|
36
46
|
|
|
37
47
|
## Install
|
|
38
48
|
|
|
@@ -114,6 +124,31 @@ end
|
|
|
114
124
|
method_1
|
|
115
125
|
```
|
|
116
126
|
|
|
127
|
+
### Configuration
|
|
128
|
+
|
|
129
|
+
You can configure a bit `MicroBench` to have an even simpler time using it afterwards. Here's how:
|
|
130
|
+
|
|
131
|
+
```ruby
|
|
132
|
+
MicroBench.configure do |config|
|
|
133
|
+
config.formatter = ->(duration) { "#{duration.round} seconds" }
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
MicroBench.start
|
|
137
|
+
sleep 2
|
|
138
|
+
MicroBench.duration == "2 seconds"
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
There are some default formatters that you can set:
|
|
142
|
+
|
|
143
|
+
| id | result | description |
|
|
144
|
+
| --------- | ---------------------------- | ---------------------------------------- |
|
|
145
|
+
| `default` | `722.327823832` | the raw original float, for computation |
|
|
146
|
+
| `simple` | `722.33` | rounds to 2 digits |
|
|
147
|
+
| `mmss` | `"12:02.328"` | Easy to understand, lossless and compact |
|
|
148
|
+
| `human` | `"12 minutes and 2 seconds"` | For humans, clutters logs |
|
|
149
|
+
|
|
150
|
+
To use one of those, simply write `config.formatter = :simple` instead of a lambda.
|
|
151
|
+
|
|
117
152
|
## Versioning
|
|
118
153
|
|
|
119
154
|
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/klaxit/micro_bench/tags).
|
data/lib/micro_bench.rb
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module MicroBench
|
|
2
4
|
class << self
|
|
5
|
+
# Configure MicroBench.
|
|
6
|
+
#
|
|
7
|
+
# == Example usage:
|
|
8
|
+
# MicroBench.configure do |config|
|
|
9
|
+
# config.formatter = proc { |duration| duration.ceil }
|
|
10
|
+
# end
|
|
11
|
+
def configure(&block)
|
|
12
|
+
block.call(configurations)
|
|
13
|
+
nil
|
|
14
|
+
end
|
|
15
|
+
|
|
3
16
|
# Start a benchmark
|
|
4
17
|
#
|
|
5
18
|
# == Parameters:
|
|
@@ -52,11 +65,17 @@ module MicroBench
|
|
|
52
65
|
# MicroBench.stop(:my_benchmark)
|
|
53
66
|
#
|
|
54
67
|
def duration(bench_id = nil)
|
|
55
|
-
|
|
68
|
+
configurations.formatter.call(
|
|
69
|
+
benchmarks[benchmark_key(bench_id)]&.duration
|
|
70
|
+
)
|
|
56
71
|
end
|
|
57
72
|
|
|
58
73
|
private
|
|
59
74
|
|
|
75
|
+
def configurations
|
|
76
|
+
@configurations ||= Configurations.new
|
|
77
|
+
end
|
|
78
|
+
|
|
60
79
|
def benchmarks
|
|
61
80
|
@benchmarks ||= {}
|
|
62
81
|
end
|
|
@@ -79,3 +98,4 @@ module MicroBench
|
|
|
79
98
|
end
|
|
80
99
|
|
|
81
100
|
require "micro_bench/benchmark"
|
|
101
|
+
require "micro_bench/configurations"
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class MicroBench::Configurations
|
|
4
|
+
attr_reader :formatter
|
|
5
|
+
|
|
6
|
+
# Initialize with a default formatters that changes nothing.
|
|
7
|
+
def initialize
|
|
8
|
+
@formatter = method(:default_formatter)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Set formatter to change {MicroBench.duration} results.
|
|
12
|
+
#
|
|
13
|
+
# == Parameters:
|
|
14
|
+
# value::
|
|
15
|
+
# It can be a proc that receives a duration float in seconds and returns any
|
|
16
|
+
# formatted value. Or it can be one of the default values, +"simple"+,
|
|
17
|
+
# +"mmss"+ or +"human"+. If you set it to +nil+ or +"default"+, the
|
|
18
|
+
# formatter will be ignored, and the result will be the raw float.
|
|
19
|
+
def formatter=(value)
|
|
20
|
+
# This ensures that both Proc and Method can be used there. Or even a user
|
|
21
|
+
# defined class that responds to call.
|
|
22
|
+
if value.respond_to?(:call)
|
|
23
|
+
@formatter = value
|
|
24
|
+
return
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
formatter_method =
|
|
28
|
+
case value.to_s
|
|
29
|
+
when "", "default"
|
|
30
|
+
:default_formatter
|
|
31
|
+
when "simple"
|
|
32
|
+
:simple_formatter
|
|
33
|
+
when "mmss"
|
|
34
|
+
:mmss_formatter
|
|
35
|
+
when "human"
|
|
36
|
+
:human_formatter
|
|
37
|
+
else
|
|
38
|
+
raise ArgumentError, "formatter must be callable or a default string"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
@formatter = method(formatter_method)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def default_formatter(duration)
|
|
47
|
+
duration
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def simple_formatter(duration)
|
|
51
|
+
duration.round(2)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def mmss_formatter(duration)
|
|
55
|
+
ss, ms = duration.divmod(1)
|
|
56
|
+
mm, ss = ss.divmod(60)
|
|
57
|
+
hh, mm = mm.divmod(60)
|
|
58
|
+
|
|
59
|
+
# Format ms to have only 3 digits.
|
|
60
|
+
ms = (ms * 1_000).round
|
|
61
|
+
|
|
62
|
+
return format("%02d:%02d:%02d.%03d", hh, mm, ss, ms) if hh > 0
|
|
63
|
+
return format("%02d:%02d.%03d", mm, ss, ms) if mm > 0
|
|
64
|
+
return format("%d.%03d", ss, ms)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def human_formatter(duration)
|
|
68
|
+
ss = duration.round
|
|
69
|
+
mm, ss = ss.divmod(60)
|
|
70
|
+
hh, mm = mm.divmod(60)
|
|
71
|
+
|
|
72
|
+
human_unit = ->(value, name) { "#{value} #{name}#{"s" unless value == 1}" }
|
|
73
|
+
|
|
74
|
+
hours = human_unit[hh, "hour"]
|
|
75
|
+
minutes = human_unit[mm, "minute"]
|
|
76
|
+
seconds = human_unit[ss, "second"]
|
|
77
|
+
|
|
78
|
+
human_join = ->(*array) { array[0..-2].join(", ") + " and #{array.last}" }
|
|
79
|
+
|
|
80
|
+
return human_join[hours, minutes, seconds] if hh > 0
|
|
81
|
+
return human_join[minutes, seconds] if mm > 0
|
|
82
|
+
return seconds
|
|
83
|
+
end
|
|
84
|
+
end
|
data/lib/micro_bench/version.rb
CHANGED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
describe MicroBench::Configurations do
|
|
4
|
+
let(:duration) { rand(10) + rand }
|
|
5
|
+
|
|
6
|
+
describe "#default_formatter" do
|
|
7
|
+
it "does nothing" do
|
|
8
|
+
expect(subject.send(:default_formatter, duration)).to eq duration
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe "#simple_formatter" do
|
|
13
|
+
it "rounds" do
|
|
14
|
+
expect(subject.send(:simple_formatter, duration)).to eq duration.round(2)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "#mmss_formatter" do
|
|
19
|
+
it "gives hh:mm:ss.s" do
|
|
20
|
+
expect(subject.send(:mmss_formatter, 457927.127)).to eq "127:12:07.127"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe "#human_formatter" do
|
|
25
|
+
it "gives a text" do
|
|
26
|
+
expect(subject.send(:human_formatter, 457287.4699882))
|
|
27
|
+
.to eq "127 hours, 1 minute and 27 seconds"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
describe MicroBench do
|
|
4
4
|
it "gives seconds duration doing something" do
|
|
@@ -91,10 +91,10 @@ describe MicroBench do
|
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
it "allows referencing a benchmark from a Proc / Block / Lambda" do
|
|
94
|
-
|
|
94
|
+
described_class.start
|
|
95
95
|
# from a Proc
|
|
96
96
|
proc = Proc.new do
|
|
97
|
-
expect(
|
|
97
|
+
expect(described_class.duration).to_not be_nil
|
|
98
98
|
end
|
|
99
99
|
proc.call
|
|
100
100
|
# from a Block
|
|
@@ -102,12 +102,28 @@ describe MicroBench do
|
|
|
102
102
|
yield
|
|
103
103
|
end
|
|
104
104
|
my_method do
|
|
105
|
-
expect(
|
|
105
|
+
expect(described_class.duration).to_not be_nil
|
|
106
106
|
end
|
|
107
107
|
# from a Lambda
|
|
108
108
|
l = lambda do
|
|
109
|
-
expect(
|
|
109
|
+
expect(described_class.duration).to_not be_nil
|
|
110
110
|
end
|
|
111
111
|
l.call
|
|
112
112
|
end
|
|
113
|
+
|
|
114
|
+
it "formats duration when configured with an id" do
|
|
115
|
+
described_class.configure do |config|
|
|
116
|
+
config.formatter = :human
|
|
117
|
+
end
|
|
118
|
+
described_class.start
|
|
119
|
+
expect(described_class.duration).to eq "0 seconds"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it "formats duration when using a callable" do
|
|
123
|
+
described_class.configure do |config|
|
|
124
|
+
config.formatter = proc { "result" }
|
|
125
|
+
end
|
|
126
|
+
described_class.start
|
|
127
|
+
expect(described_class.duration).to eq "result"
|
|
128
|
+
end
|
|
113
129
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: micro_bench
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Cyrille Courtière
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-06-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: byebug
|
|
@@ -38,7 +38,7 @@ dependencies:
|
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '3.8'
|
|
41
|
-
description:
|
|
41
|
+
description:
|
|
42
42
|
email:
|
|
43
43
|
- cyrille@klaxit.com
|
|
44
44
|
executables: []
|
|
@@ -48,14 +48,16 @@ files:
|
|
|
48
48
|
- README.md
|
|
49
49
|
- lib/micro_bench.rb
|
|
50
50
|
- lib/micro_bench/benchmark.rb
|
|
51
|
+
- lib/micro_bench/configurations.rb
|
|
51
52
|
- lib/micro_bench/version.rb
|
|
52
|
-
- spec/micro_bench/
|
|
53
|
+
- spec/micro_bench/configurations_spec.rb
|
|
54
|
+
- spec/micro_bench_spec.rb
|
|
53
55
|
- spec/spec_helper.rb
|
|
54
56
|
homepage: http://github.com/klaxit/micro_bench
|
|
55
57
|
licenses:
|
|
56
58
|
- MIT
|
|
57
59
|
metadata: {}
|
|
58
|
-
post_install_message:
|
|
60
|
+
post_install_message:
|
|
59
61
|
rdoc_options: []
|
|
60
62
|
require_paths:
|
|
61
63
|
- lib
|
|
@@ -70,11 +72,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
70
72
|
- !ruby/object:Gem::Version
|
|
71
73
|
version: '0'
|
|
72
74
|
requirements: []
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
signing_key:
|
|
75
|
+
rubygems_version: 3.1.0.pre3
|
|
76
|
+
signing_key:
|
|
76
77
|
specification_version: 4
|
|
77
78
|
summary: Dead simple benchmarks
|
|
78
79
|
test_files:
|
|
79
|
-
- spec/micro_bench/
|
|
80
|
+
- spec/micro_bench/configurations_spec.rb
|
|
81
|
+
- spec/micro_bench_spec.rb
|
|
80
82
|
- spec/spec_helper.rb
|