benchmeth 0.0.1 → 0.2.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 02f90c97b8afdc34db17a600c5927231d4ca14cedb2680041952695789daa14c
4
+ data.tar.gz: 159e262d33720193f70d30cadb0d4ca6908894e87130ab4faeb70daa70c7b96e
5
+ SHA512:
6
+ metadata.gz: b9ef7c3f9ade012da933b74ae7da18a696f7a6b9339191970ee43a78e295ee83563410c2e06bf6ea0d6b0b25727ff8fcbc85c9a1fcd9227b2c1325292703ac5e
7
+ data.tar.gz: c203a49b6235877692c839449d478838f25aaa6525d4f76fed4c22376d40fc674ec4dec720d7121e8883a15be77b2eba971b57cf32d377917556084884dfaa78
data/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ ## 0.2.0 (2022-09-06)
2
+
3
+ - Use monotonic time
4
+ - Dropped support for Ruby < 2.7
5
+
6
+ ## 0.1.1 (2017-03-31)
7
+
8
+ - Added `use_notifications` option
9
+
10
+ ## 0.1.0 (2011-10-14)
11
+
12
+ - First release
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014-2022 Andrew Kane
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,73 +1,86 @@
1
1
  # Benchmeth
2
2
 
3
- The super easy way to benchmark methods.
3
+ The super easy way to benchmark methods in a live application
4
4
 
5
5
  ```ruby
6
- gem "benchmeth"
6
+ class Person
7
+ def compute
8
+ # boom
9
+ end
10
+ benchmark :compute
11
+ end
7
12
  ```
8
13
 
9
- Just say which methods to benchmark and what you'd like to do with the results.
14
+ Works with class methods, too
10
15
 
11
16
  ```ruby
12
- def compute
13
- puts "CRUNCH!!"
17
+ class Person
18
+ def self.compute
19
+ # yolo
20
+ end
21
+ class << self
22
+ benchmark :compute
23
+ end
14
24
  end
25
+ ```
15
26
 
16
- benchmeth :compute do |method_name, realtime|
17
- puts "%s : %.2f ms" % [method_name, realtime * 1000]
18
- # Or log them.
19
- end
27
+ ## Installation
20
28
 
21
- compute
29
+ Add this line to your application’s Gemfile:
22
30
 
23
- # Output:
24
- # CRUNCH!!
25
- # compute : 0.09 ms
31
+ ```ruby
32
+ gem "benchmeth"
26
33
  ```
27
34
 
28
- To call a method without benchmarking, use:
35
+ ## How to Use
36
+
37
+ By default, benchmark data is written to `stdout` in the following format:
29
38
 
30
- ```ruby
31
- compute_without_benchmark
39
+ ```
40
+ compute : 1000 ms
32
41
  ```
33
42
 
34
- ## Instance Methods
43
+ but you can easily do whatever you want with it.
35
44
 
36
45
  ```ruby
37
- class Person
46
+ Benchmeth.on_benchmark do |method_name, seconds|
47
+ puts "#{method_name} took #{seconds} seconds!"
48
+ end
49
+ ```
38
50
 
39
- def work(seconds)
40
- puts "Working for #{seconds} seconds"
41
- sleep(seconds)
42
- end
51
+ To call a method without benchmarking, append `_without_benchmark` to the name.
43
52
 
44
- def play
45
- puts "Time to play!"
46
- sleep(rand * 4)
47
- end
53
+ ## Active Support Notifications
48
54
 
49
- # This must come after the methods are defined.
50
- benchmeth :work, :play do |method_name, realtime|
51
- puts "%s : %.2f ms" % [method_name, realtime * 1000]
52
- end
55
+ You can switch to Active Support notifications with:
53
56
 
54
- end
57
+ ```ruby
58
+ Benchmeth.use_notifications = true
55
59
  ```
56
60
 
57
- ## Class Methods
61
+ And subscribe with:
58
62
 
59
63
  ```ruby
60
- class Person
64
+ ActiveSupport::Notifications.monotonic_subscribe "benchmark.benchmeth" do |*args|
65
+ event = ActiveSupport::Notifications::Event.new(*args)
66
+ puts "%s : %d ms" % [event.payload[:name], event.duration]
67
+ end
68
+ ```
61
69
 
62
- def self.count
63
- 2
64
- end
70
+ ## Contributing
65
71
 
66
- class << self
67
- benchmeth :count do |method_name, realtime|
68
- puts "%s : %.2f ms" % [method_name, realtime * 1000]
69
- end
70
- end
72
+ Everyone is encouraged to help improve this project. Here are a few ways you can help:
71
73
 
72
- end
74
+ - [Report bugs](https://github.com/ankane/benchmeth/issues)
75
+ - Fix bugs and [submit pull requests](https://github.com/ankane/benchmeth/pulls)
76
+ - Write, clarify, or fix documentation
77
+ - Suggest or add new features
78
+
79
+ To get started with development:
80
+
81
+ ```sh
82
+ git clone https://github.com/ankane/benchmeth.git
83
+ cd benchmeth
84
+ bundle install
85
+ bundle exec rake test
73
86
  ```
@@ -1,3 +1,3 @@
1
1
  module Benchmeth
2
- VERSION = "0.0.1"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/benchmeth.rb CHANGED
@@ -1,38 +1,70 @@
1
1
  require "benchmeth/version"
2
- require "benchmark"
2
+
3
+ # :( Global
4
+ $benchmeth_main = self
3
5
 
4
6
  module Benchmeth
7
+ class << self
8
+ attr_accessor :use_notifications, :on_benchmark_block
9
+ end
10
+ self.use_notifications = false
11
+ self.on_benchmark_block = lambda do |method, realtime|
12
+ puts "%s : %d ms" % [method, realtime * 1000]
13
+ end
5
14
 
6
- def self.included(base)
7
- base.send :extend, ClassMethods
8
- base.send :include, InstanceMethods
15
+ def self.on_benchmark(&block)
16
+ if block_given?
17
+ self.on_benchmark_block = block
18
+ else
19
+ self.on_benchmark_block
20
+ end
9
21
  end
10
22
 
11
- module ClassMethods
23
+ def self.monotonic_time
24
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
25
+ end
12
26
 
13
- def benchmeth(*method_names, &block)
27
+ module ClassMethods
28
+ def benchmark(*method_names)
14
29
  method_names.each do |method_name|
15
30
  method_name = method_name.to_sym
16
- self.send :alias_method, :"#{method_name}_without_benchmark", method_name
17
- self.send :define_method, method_name do |*args|
18
- result = nil
19
- realtime = Benchmark.realtime { result = self.send(:"#{method_name}_without_benchmark", *args) }
20
- block.call(method_name, realtime)
21
- result
31
+ send :alias_method, :"#{method_name}_without_benchmark", method_name
32
+ send :define_method, method_name do |*args, &block|
33
+ method_prefix =
34
+ case self
35
+ when $benchmeth_main
36
+ ""
37
+ when Class
38
+ "#{name}."
39
+ else
40
+ "#{self.class.name}#"
41
+ end
42
+
43
+ if Benchmeth.use_notifications
44
+ payload = {
45
+ name: "#{method_prefix}#{method_name}"
46
+ }
47
+ ActiveSupport::Notifications.instrument "benchmark.benchmeth", payload do
48
+ send(:"#{method_name}_without_benchmark", *args, &block)
49
+ end
50
+ else
51
+ start_time = Benchmeth.monotonic_time
52
+ result = send(:"#{method_name}_without_benchmark", *args, &block)
53
+ realtime = Benchmeth.monotonic_time - start_time
54
+ Benchmeth.on_benchmark.call("#{method_prefix}#{method_name}", realtime)
55
+ result
56
+ end
22
57
  end
23
58
  end
24
59
  end
25
-
26
60
  end
27
61
 
28
62
  module InstanceMethods
29
-
30
- def benchmeth(*method_names, &block)
31
- self.class.benchmeth(*method_names, &block)
63
+ def benchmark(*method_names, &block)
64
+ self.class.benchmark(*method_names, &block)
32
65
  end
33
-
34
66
  end
35
-
36
67
  end
37
68
 
38
- Object.send :include, Benchmeth
69
+ Object.extend Benchmeth::ClassMethods
70
+ Object.include Benchmeth::InstanceMethods
metadata CHANGED
@@ -1,52 +1,47 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: benchmeth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
5
- prerelease:
4
+ version: 0.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Andrew Kane
9
- autorequire:
8
+ autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2011-10-14 00:00:00.000000000Z
11
+ date: 2022-09-06 00:00:00.000000000 Z
13
12
  dependencies: []
14
- description: The super easy way to benchmark methods
15
- email:
16
- - andrew@getformidable.com
13
+ description:
14
+ email: andrew@ankane.org
17
15
  executables: []
18
16
  extensions: []
19
17
  extra_rdoc_files: []
20
18
  files:
21
- - .gitignore
22
- - Gemfile
19
+ - CHANGELOG.md
20
+ - LICENSE.txt
23
21
  - README.md
24
- - Rakefile
25
- - benchmeth.gemspec
26
22
  - lib/benchmeth.rb
27
23
  - lib/benchmeth/version.rb
28
24
  homepage: https://github.com/ankane/benchmeth
29
- licenses: []
30
- post_install_message:
25
+ licenses:
26
+ - MIT
27
+ metadata: {}
28
+ post_install_message:
31
29
  rdoc_options: []
32
30
  require_paths:
33
31
  - lib
34
32
  required_ruby_version: !ruby/object:Gem::Requirement
35
- none: false
36
33
  requirements:
37
- - - ! '>='
34
+ - - ">="
38
35
  - !ruby/object:Gem::Version
39
- version: '0'
36
+ version: '2.7'
40
37
  required_rubygems_version: !ruby/object:Gem::Requirement
41
- none: false
42
38
  requirements:
43
- - - ! '>='
39
+ - - ">="
44
40
  - !ruby/object:Gem::Version
45
41
  version: '0'
46
42
  requirements: []
47
- rubyforge_project:
48
- rubygems_version: 1.8.10
49
- signing_key:
50
- specification_version: 3
43
+ rubygems_version: 3.3.7
44
+ signing_key:
45
+ specification_version: 4
51
46
  summary: The super easy way to benchmark methods
52
47
  test_files: []
data/.gitignore DELETED
@@ -1,17 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source 'http://rubygems.org'
2
-
3
- # Specify your gem's dependencies in benchmeth.gemspec
4
- gemspec
data/Rakefile DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env rake
2
- require "bundler/gem_tasks"
data/benchmeth.gemspec DELETED
@@ -1,17 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/benchmeth/version', __FILE__)
3
-
4
- Gem::Specification.new do |gem|
5
- gem.authors = ["Andrew Kane"]
6
- gem.email = ["andrew@getformidable.com"]
7
- gem.description = %q{The super easy way to benchmark methods}
8
- gem.summary = %q{The super easy way to benchmark methods}
9
- gem.homepage = "https://github.com/ankane/benchmeth"
10
-
11
- gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
- gem.files = `git ls-files`.split("\n")
13
- gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
- gem.name = "benchmeth"
15
- gem.require_paths = ["lib"]
16
- gem.version = Benchmeth::VERSION
17
- end