timeasure 0.1.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 +4 -4
- data/CHANGELOG.md +30 -0
- data/README.md +65 -1
- data/lib/timeasure.rb +2 -2
- data/lib/timeasure/class_methods.rb +22 -2
- data/lib/timeasure/version.rb +1 -1
- data/timeasure.gemspec +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 646792d500a9a61b929dd067f9c1b48b9bf30b2d
|
4
|
+
data.tar.gz: 1c0b5af7065eb1a950e201521ca7ec2f5c644964
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81af656e98f415dddf152dbec13530c84d4506c64eac0fd13b6f217aad76598dd10251c18239de1c9b69eb8fabc18d732531ce45fe188a73a144453580be486a
|
7
|
+
data.tar.gz: b2062fb31932f6087a6ec43b7f8f7991a868f8b8ff4081e7579358fa9798a1438e377144a257cedc2d36aec0a6570ba772b3c07d8d2fc0bbc9d366b289cc7919
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Changelog
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
5
|
+
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
6
|
+
|
7
|
+
## [Unreleased]
|
8
|
+
|
9
|
+
## [0.2.0] - 2018-03-12
|
10
|
+
### Added
|
11
|
+
- New class macros for tracking private methods in both inline and scoped visibility declaration.
|
12
|
+
|
13
|
+
### Changed
|
14
|
+
- Start using `Process.clock_gettime(Process::CLOCK_MONOTONIC)` instead of `Time.now` for time tracking
|
15
|
+
- Bumped up required Ruby version from 2.0 to 2.1
|
16
|
+
|
17
|
+
## [0.1.1] - 2018-02-24
|
18
|
+
### Added
|
19
|
+
- Specs for describing the proper way to track private methods.
|
20
|
+
|
21
|
+
### Fixed
|
22
|
+
- Minor performance issue in class macros
|
23
|
+
|
24
|
+
## [0.1.0] - 2018-02-24
|
25
|
+
### Added
|
26
|
+
- Timeasure main code
|
27
|
+
- Timeasure profiler
|
28
|
+
|
29
|
+
[0.2.0]: https://github.com/Riskified/timeasure/compare/v0.1.1...v0.2.0
|
30
|
+
[0.1.1]: https://github.com/Riskified/timeasure/compare/v0.1.0...v0.1.1
|
data/README.md
CHANGED
@@ -39,7 +39,7 @@ Timeasure is developed and maintained by [Eliav Lavi](http://www.eliavlavi.com)
|
|
39
39
|
|
40
40
|
## Requirements
|
41
41
|
|
42
|
-
Ruby 2.
|
42
|
+
Ruby 2.1 or a later version is mandatory. (Timeasure uses `Module#prepend` introduced in Ruby 2.0 and `Process::CLOCK_MONOTONIC` introduced in Ruby 2.1.)
|
43
43
|
|
44
44
|
## Installation
|
45
45
|
|
@@ -78,6 +78,70 @@ class Foo
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
```
|
81
|
+
**An Important Note Regarding Private Methods**
|
82
|
+
|
83
|
+
If you need to track any private methods - either class methods or instance methods - use the designated class macros for that:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
class Foo
|
87
|
+
include Timeasure
|
88
|
+
tracked_class_methods :a_class_method_that_calls_private_methods
|
89
|
+
tracked_private_class_methods :a_scoped_private_class_method, :an_inline_private_class_method
|
90
|
+
|
91
|
+
class << self
|
92
|
+
def a_class_method_that_calls_private_methods
|
93
|
+
a_scoped_private_class_method
|
94
|
+
an_inline_private_class_method
|
95
|
+
end
|
96
|
+
|
97
|
+
def a_scoped_private_class_method
|
98
|
+
# some private class-level stuff that can benefit from measuring runtime...
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.an_inline_private_class_method
|
103
|
+
# some other private class-level stuff that can benefit from measuring runtime...
|
104
|
+
end
|
105
|
+
end
|
106
|
+
```
|
107
|
+
|
108
|
+
And the instance-level equivalent:
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
class Foo
|
112
|
+
include Timeasure
|
113
|
+
tracked_instance_methods :a_instance_method_that_calls_private_methods
|
114
|
+
tracked_private_instance_methods :a_scoped_private_instance_method, :an_inline_private_instance_method
|
115
|
+
|
116
|
+
class << self
|
117
|
+
def a_instance_method_that_calls_private_methods
|
118
|
+
a_scoped_private_instance_method
|
119
|
+
an_inline_private_instance_method
|
120
|
+
end
|
121
|
+
|
122
|
+
def a_scoped_private_instance_method
|
123
|
+
# some private instance-level stuff that can benefit from measuring runtime...
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def self.an_inline_private_instance_method
|
128
|
+
# some other private instance-level stuff that can benefit from measuring runtime...
|
129
|
+
end
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
**ATTENTION!**
|
134
|
+
|
135
|
+
**Declaring the tracking of private methods with `tracked_class_methods` or `tracked_instance_methods` will end up in `NoMethodError` upon calling their triggering method!**
|
136
|
+
|
137
|
+
Also, tracking your public methods with `tracked_private_class_methods` or `tracked_private_instance_methods` will make your class' interface inaccessible.
|
138
|
+
The reason for these two is that since Timeasure is declared at the top of the class,
|
139
|
+
it cannot know in advance which methods will be declared as private, so you need to specify this explicitly.
|
140
|
+
|
141
|
+
As a side note, it could be claimed that as a rule of thumb, if you find yourself measuring private methods,
|
142
|
+
this might be a good idea to invest in refactoring this area of code and [Extract Class](https://refactoring.guru/extract-class).
|
143
|
+
However, this is not always possible, of course, especially when working on legacy code.
|
144
|
+
Hence, this feature of Timeasure should be considered as somewhat of a last resort and be handled with care.
|
81
145
|
|
82
146
|
#### 2. Define the Boundaries of the Tracked Transaction
|
83
147
|
**Preparing for Method Tracking**
|
data/lib/timeasure.rb
CHANGED
@@ -27,9 +27,9 @@ module Timeasure
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def measure(klass_name: nil, method_name: nil, segment: nil, metadata: nil)
|
30
|
-
t0 =
|
30
|
+
t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
31
31
|
block_return_value = yield if block_given?
|
32
|
-
t1 =
|
32
|
+
t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
33
33
|
|
34
34
|
begin
|
35
35
|
measurement = Timeasure::Measurement.new(klass_name: klass_name.to_s, method_name: method_name.to_s,
|
@@ -1,19 +1,27 @@
|
|
1
1
|
module Timeasure
|
2
2
|
module ClassMethods
|
3
3
|
def tracked_instance_methods(*method_names)
|
4
|
-
instance_interceptor = const_get("#{timeasure_name}InstanceInterceptor")
|
5
4
|
method_names.each do |method_name|
|
6
5
|
add_method_to_interceptor(instance_interceptor, method_name)
|
7
6
|
end
|
8
7
|
end
|
9
8
|
|
10
9
|
def tracked_class_methods(*method_names)
|
11
|
-
class_interceptor = const_get("#{timeasure_name}ClassInterceptor")
|
12
10
|
method_names.each do |method_name|
|
13
11
|
add_method_to_interceptor(class_interceptor, method_name)
|
14
12
|
end
|
15
13
|
end
|
16
14
|
|
15
|
+
def tracked_private_instance_methods(*method_names)
|
16
|
+
tracked_instance_methods(*method_names)
|
17
|
+
method_names.each { |method_name| privatize_interceptor_method(instance_interceptor, method_name) }
|
18
|
+
end
|
19
|
+
|
20
|
+
def tracked_private_class_methods(*method_names)
|
21
|
+
tracked_class_methods(*method_names)
|
22
|
+
method_names.each { |method_name| privatize_interceptor_method(class_interceptor, method_name) }
|
23
|
+
end
|
24
|
+
|
17
25
|
def timeasure_name
|
18
26
|
name.gsub('::', '_')
|
19
27
|
end
|
@@ -29,5 +37,17 @@ module Timeasure
|
|
29
37
|
end
|
30
38
|
end
|
31
39
|
end
|
40
|
+
|
41
|
+
def privatize_interceptor_method(interceptor, method_name)
|
42
|
+
interceptor.class_eval { private method_name }
|
43
|
+
end
|
44
|
+
|
45
|
+
def instance_interceptor
|
46
|
+
const_get("#{timeasure_name}InstanceInterceptor")
|
47
|
+
end
|
48
|
+
|
49
|
+
def class_interceptor
|
50
|
+
const_get("#{timeasure_name}ClassInterceptor")
|
51
|
+
end
|
32
52
|
end
|
33
53
|
end
|
data/lib/timeasure/version.rb
CHANGED
data/timeasure.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.test_files = spec.files.grep(%r{^spec/})
|
20
20
|
spec.require_paths = ['lib', 'lib/timeasure', 'lib/timeasure/profiling']
|
21
21
|
|
22
|
-
spec.required_ruby_version = '>= 2.
|
22
|
+
spec.required_ruby_version = '>= 2.1'
|
23
23
|
spec.add_development_dependency 'bundler', '~> 1.6'
|
24
24
|
spec.add_development_dependency 'coveralls'
|
25
25
|
spec.add_development_dependency 'rake', '~> 12.0'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timeasure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eliav Lavi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -79,6 +79,7 @@ files:
|
|
79
79
|
- ".gitignore"
|
80
80
|
- ".rspec"
|
81
81
|
- ".rubocop.yml"
|
82
|
+
- CHANGELOG.md
|
82
83
|
- Gemfile
|
83
84
|
- LICENSE.txt
|
84
85
|
- README.md
|
@@ -106,7 +107,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
106
107
|
requirements:
|
107
108
|
- - ">="
|
108
109
|
- !ruby/object:Gem::Version
|
109
|
-
version: '2.
|
110
|
+
version: '2.1'
|
110
111
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
112
|
requirements:
|
112
113
|
- - ">="
|