gem_footprint_analyzer 0.1.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 +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +424 -0
- data/Rakefile +6 -0
- data/exe/analyze_requires +42 -0
- data/gem_footprint_analyzer.gemspec +28 -0
- data/lib/gem_footprint_analyzer.rb +10 -0
- data/lib/gem_footprint_analyzer/analyzer.rb +84 -0
- data/lib/gem_footprint_analyzer/average_runner.rb +62 -0
- data/lib/gem_footprint_analyzer/json_formatter.rb +8 -0
- data/lib/gem_footprint_analyzer/pipe_transport.rb +70 -0
- data/lib/gem_footprint_analyzer/require_spy.rb +31 -0
- data/lib/gem_footprint_analyzer/text_formatter.rb +50 -0
- data/lib/gem_footprint_analyzer/version.rb +3 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 01fceb1ae268426dbc40be479314460b27a4640b869ae5d4d644f7e2cdee5f70
|
4
|
+
data.tar.gz: 4bede18980190bd8c3aa847e96d9075610263f3d9453946f4f375223cffeb958
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4b1692cd24a9f7c6b3223f4896130cb64d1d4e0fbcc397e0615a669ec314280de7f2d15e83144defd656dcc16f8c7071ff1e2ef3cc1c8062d620fdc9b635cb8c
|
7
|
+
data.tar.gz: 7b68b3d7dd7ec50087a200a46e99cefbfed19e09711ba3bc2cb5c7b6ba7814d406adc7f4b557b4a1201c6e9ea36695649742ecde73037ef545331292f275beaa
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
10
|
+
orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at maciek@dubinski.net. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at [http://contributor-covenant.org/version/1/4][version]
|
72
|
+
|
73
|
+
[homepage]: http://contributor-covenant.org
|
74
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 Maciek Dubiński
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,424 @@
|
|
1
|
+
# GemFootprintAnalyzer
|
2
|
+
|
3
|
+
A tool for analyzing time and RSS footprint of gems or standard library requires, it's currently in a 'work in progress' state (developed on ruby-2.5.1 / macOS).
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'gem_footprint_analyzer'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install gem_footprint_analyzer
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Analyze a standard library require or a gem. In the gem case, make sure it's included in the Gemfile.
|
24
|
+
|
25
|
+
Example usages:
|
26
|
+
|
27
|
+
### timeout
|
28
|
+
```
|
29
|
+
$ bundle exec analyze_requires timeout
|
30
|
+
name time RSS after
|
31
|
+
-----------------------------
|
32
|
+
timeout 0.0032s 2140KB
|
33
|
+
```
|
34
|
+
|
35
|
+
### net/http
|
36
|
+
```
|
37
|
+
$ bundle exec analyze_requires net/http
|
38
|
+
name time RSS after
|
39
|
+
-------------------------------
|
40
|
+
socket.so 0.0019s 4920KB
|
41
|
+
io/wait 0.0009s 5296KB
|
42
|
+
socket 0.0108s 5296KB
|
43
|
+
timeout 0.0014s 5736KB
|
44
|
+
zlib 0.0012s 5924KB
|
45
|
+
-------------------------------
|
46
|
+
net/http 0.0476s 6712KB
|
47
|
+
```
|
48
|
+
|
49
|
+
### activesupport/all
|
50
|
+
```
|
51
|
+
$ bundle exec analyze_requires activesupport active_support/all
|
52
|
+
name time RSS after
|
53
|
+
--------------------------------------------------------------------------------------
|
54
|
+
securerandom 0.0022s 2728KB
|
55
|
+
concurrent/constants 0.0005s 4168KB
|
56
|
+
concurrent/utility/engine 0.0006s 4268KB
|
57
|
+
concurrent/synchronization/abstract_object 0.0006s 4360KB
|
58
|
+
concurrent/utility/native_extension_loader 0.0015s 5008KB
|
59
|
+
concurrent/synchronization/mri_object 0.0006s 5132KB
|
60
|
+
concurrent/synchronization/jruby_object 0.0006s 5172KB
|
61
|
+
concurrent/synchronization/rbx_object 0.0006s 5212KB
|
62
|
+
concurrent/synchronization/truffle_object 0.0007s 5312KB
|
63
|
+
concurrent/synchronization/object 0.0010s 5416KB
|
64
|
+
concurrent/synchronization/volatile 0.0006s 5536KB
|
65
|
+
concurrent/synchronization/abstract_lockable_object 0.0007s 5656KB
|
66
|
+
concurrent/synchronization/mri_lockable_object 0.0008s 5776KB
|
67
|
+
concurrent/synchronization/jruby_lockable_object 0.0005s 5840KB
|
68
|
+
concurrent/synchronization/rbx_lockable_object 0.0007s 5864KB
|
69
|
+
concurrent/synchronization/truffle_lockable_object 0.0004s 5884KB
|
70
|
+
concurrent/synchronization/lockable_object 0.0005s 5936KB
|
71
|
+
concurrent/synchronization/condition 0.0007s 5984KB
|
72
|
+
concurrent/synchronization/lock 0.0005s 6012KB
|
73
|
+
concurrent/synchronization 0.0745s 6012KB
|
74
|
+
concurrent/collection/map/non_concurrent_map_backend 0.0010s 6144KB
|
75
|
+
concurrent/collection/map/mri_map_backend 0.0018s 6144KB
|
76
|
+
concurrent/map 0.0894s 6144KB
|
77
|
+
active_support/core_ext/array/prepend_and_append 0.0004s 6156KB
|
78
|
+
active_support/core_ext/regexp 0.0004s 6180KB
|
79
|
+
active_support/core_ext/hash/deep_merge 0.0005s 6280KB
|
80
|
+
active_support/core_ext/hash/except 0.0005s 6304KB
|
81
|
+
active_support/core_ext/hash/slice 0.0006s 6424KB
|
82
|
+
i18n/version 0.0003s 6512KB
|
83
|
+
i18n/exceptions 0.0012s 6688KB
|
84
|
+
i18n/interpolate/ruby 0.0006s 6776KB
|
85
|
+
i18n 0.0114s 6776KB
|
86
|
+
active_support/lazy_load_hooks 0.0006s 6812KB
|
87
|
+
i18n/config 0.0009s 6932KB
|
88
|
+
active_support/i18n 0.0374s 6932KB
|
89
|
+
singleton 0.0006s 6992KB
|
90
|
+
active_support/core_ext/kernel/singleton_class 0.0005s 7048KB
|
91
|
+
active_support/core_ext/module/delegation 0.0020s 7208KB
|
92
|
+
active_support/deprecation/instance_delegator 0.0068s 7208KB
|
93
|
+
active_support/notifications/instrumenter 0.0008s 7332KB
|
94
|
+
mutex_m 0.0005s 7428KB
|
95
|
+
active_support/notifications/fanout 0.0053s 7460KB
|
96
|
+
active_support/per_thread_registry 0.0005s 7480KB
|
97
|
+
active_support/notifications 0.0146s 7480KB
|
98
|
+
active_support/deprecation/behaviors 0.0153s 7480KB
|
99
|
+
active_support/deprecation/reporting 0.0010s 7560KB
|
100
|
+
active_support/deprecation/constant_accessor 0.0007s 7688KB
|
101
|
+
active_support/core_ext/module/aliasing 0.0005s 7732KB
|
102
|
+
active_support/core_ext/array/extract_options 0.0004s 7748KB
|
103
|
+
active_support/deprecation/method_wrappers 0.0052s 7748KB
|
104
|
+
active_support/deprecation/proxy_wrappers 0.0010s 7832KB
|
105
|
+
active_support/core_ext/module/deprecation 0.0005s 8276KB
|
106
|
+
active_support/deprecation 0.0723s 8276KB
|
107
|
+
active_support/inflector/inflections 0.2265s 8276KB
|
108
|
+
active_support/inflections 0.2285s 8276KB
|
109
|
+
active_support/inflector/methods 0.2426s 8284KB
|
110
|
+
active_support/dependencies/autoload 0.2438s 8284KB
|
111
|
+
active_support/version 0.0006s 8308KB
|
112
|
+
active_support/concern 0.0007s 8620KB
|
113
|
+
active_support/core_ext/module/attribute_accessors 0.0011s 8688KB
|
114
|
+
concurrent/version 0.0003s 8728KB
|
115
|
+
concurrent/errors 0.0006s 8768KB
|
116
|
+
timeout 0.0009s 9052KB
|
117
|
+
concurrent/atomic/event 0.0008s 9080KB
|
118
|
+
concurrent/concern/dereferenceable 0.0006s 9116KB
|
119
|
+
concurrent/concern/obligation 0.0107s 9116KB
|
120
|
+
logger 0.0024s 9632KB
|
121
|
+
concurrent/concern/logging 0.0029s 9632KB
|
122
|
+
concurrent/executor/executor_service 0.0035s 9632KB
|
123
|
+
concurrent/utility/at_exit 0.0010s 9640KB
|
124
|
+
concurrent/executor/abstract_executor_service 0.0173s 9640KB
|
125
|
+
concurrent/executor/serial_executor_service 0.0005s 9640KB
|
126
|
+
concurrent/executor/immediate_executor 0.0263s 9640KB
|
127
|
+
concurrent/delay 0.0523s 9648KB
|
128
|
+
concurrent/atomic_reference/concurrent_update_error 0.0004s 9656KB
|
129
|
+
concurrent/atomic_reference/direct_update 0.0005s 9672KB
|
130
|
+
concurrent/atomic_reference/numeric_cas_wrapper 0.0005s 9680KB
|
131
|
+
concurrent/atomic_reference/mutex_atomic 0.0054s 9680KB
|
132
|
+
concurrent/atomic_reference/ruby 0.0004s 9688KB
|
133
|
+
concurrent/atomic/atomic_reference 0.0179s 9688KB
|
134
|
+
concurrent/utility/processor_counter 0.0012s 9728KB
|
135
|
+
concurrent/configuration 0.0837s 9728KB
|
136
|
+
concurrent/atomic/mutex_atomic_boolean 0.0006s 9732KB
|
137
|
+
concurrent/atomic/atomic_boolean 0.0049s 9732KB
|
138
|
+
concurrent/utility/native_integer 0.0006s 9800KB
|
139
|
+
concurrent/atomic/mutex_atomic_fixnum 0.0013s 9800KB
|
140
|
+
concurrent/atomic/atomic_fixnum 0.0093s 9800KB
|
141
|
+
concurrent/atomic/cyclic_barrier 0.0010s 9816KB
|
142
|
+
concurrent/atomic/mutex_count_down_latch 0.0006s 9820KB
|
143
|
+
concurrent/atomic/java_count_down_latch 0.0005s 9832KB
|
144
|
+
concurrent/atomic/count_down_latch 0.0091s 9832KB
|
145
|
+
concurrent/atomic/read_write_lock 0.0014s 9876KB
|
146
|
+
concurrent/atomic/abstract_thread_local_var 0.0006s 9920KB
|
147
|
+
concurrent/atomic/ruby_thread_local_var 0.0015s 9920KB
|
148
|
+
concurrent/atomic/java_thread_local_var 0.0008s 9948KB
|
149
|
+
concurrent/atomic/thread_local_var 0.0145s 9956KB
|
150
|
+
concurrent/atomic/reentrant_read_write_lock 0.0162s 9956KB
|
151
|
+
concurrent/atomic/mutex_semaphore 0.0012s 10164KB
|
152
|
+
concurrent/atomic/semaphore 0.0057s 10164KB
|
153
|
+
concurrent/atomics 0.0782s 10164KB
|
154
|
+
concurrent/executor/ruby_executor_service 0.0008s 10192KB
|
155
|
+
concurrent/utility/monotonic_time 0.0006s 10208KB
|
156
|
+
concurrent/executor/ruby_thread_pool_executor 0.0070s 10208KB
|
157
|
+
concurrent/executor/thread_pool_executor 0.0076s 10208KB
|
158
|
+
concurrent/executor/cached_thread_pool 0.0083s 10208KB
|
159
|
+
concurrent/executor/fixed_thread_pool 0.0007s 10212KB
|
160
|
+
concurrent/executor/simple_executor_service 0.0008s 10236KB
|
161
|
+
concurrent/executor/indirect_immediate_executor 0.0015s 10236KB
|
162
|
+
concurrent/executor/java_executor_service 0.0009s 10260KB
|
163
|
+
concurrent/executor/java_single_thread_executor 0.0005s 10268KB
|
164
|
+
concurrent/executor/java_thread_pool_executor 0.0007s 10292KB
|
165
|
+
concurrent/executor/ruby_single_thread_executor 0.0005s 10292KB
|
166
|
+
concurrent/executor/safe_task_executor 0.0006s 10292KB
|
167
|
+
concurrent/executor/serialized_execution 0.0011s 10368KB
|
168
|
+
concurrent/executor/serialized_execution_delegator 0.0008s 10376KB
|
169
|
+
concurrent/executor/single_thread_executor 0.0006s 10380KB
|
170
|
+
concurrent/collection/copy_on_write_observer_set 0.0008s 10460KB
|
171
|
+
concurrent/collection/copy_on_notify_observer_set 0.0008s 10508KB
|
172
|
+
concurrent/concern/observable 0.0053s 10508KB
|
173
|
+
concurrent/ivar 0.0148s 10512KB
|
174
|
+
concurrent/options 0.0006s 10512KB
|
175
|
+
concurrent/scheduled_task 0.0203s 10512KB
|
176
|
+
concurrent/collection/java_non_concurrent_priority_queue 0.0006s 10564KB
|
177
|
+
concurrent/collection/ruby_non_concurrent_priority_queue 0.0008s 10564KB
|
178
|
+
concurrent/collection/non_concurrent_priority_queue 0.0096s 10640KB
|
179
|
+
concurrent/executor/timer_set 0.0420s 10644KB
|
180
|
+
concurrent/executors 0.1153s 10644KB
|
181
|
+
concurrent/agent 0.0023s 10748KB
|
182
|
+
concurrent/atom 0.0012s 10768KB
|
183
|
+
concurrent/thread_safe/util 0.0004s 10772KB
|
184
|
+
concurrent/array 0.0019s 10772KB
|
185
|
+
concurrent/hash 0.0007s 10776KB
|
186
|
+
concurrent/tuple 0.0007s 10780KB
|
187
|
+
concurrent/async 0.0012s 10780KB
|
188
|
+
concurrent/future 0.0011s 10784KB
|
189
|
+
concurrent/dataflow 0.0057s 10784KB
|
190
|
+
concurrent/maybe 0.0007s 10796KB
|
191
|
+
concurrent/exchanger 0.0063s 10796KB
|
192
|
+
concurrent/synchronization/abstract_struct 0.0009s 10848KB
|
193
|
+
concurrent/immutable_struct 0.0054s 10852KB
|
194
|
+
concurrent/mutable_struct 0.0011s 10880KB
|
195
|
+
concurrent/mvar 0.0011s 10884KB
|
196
|
+
concurrent/promise 0.0021s 10888KB
|
197
|
+
concurrent/settable_struct 0.0012s 10896KB
|
198
|
+
concurrent/timer_task 0.0016s 10940KB
|
199
|
+
concurrent/tvar 0.0013s 10984KB
|
200
|
+
concurrent/thread_safe/synchronized_delegator 0.0007s 10984KB
|
201
|
+
concurrent 0.4029s 10988KB
|
202
|
+
active_support/logger_silence 0.4127s 10988KB
|
203
|
+
active_support/logger_thread_safe_level 0.0006s 10996KB
|
204
|
+
active_support/logger 0.4257s 11084KB
|
205
|
+
active_support/core_ext/date_and_time/compatibility 0.0006s 11144KB
|
206
|
+
active_support 0.6941s 11144KB
|
207
|
+
date_core 0.0013s 11520KB
|
208
|
+
date 0.0020s 11520KB
|
209
|
+
time 0.0025s 11616KB
|
210
|
+
active_support/core_ext/object/acts_like 0.0003s 11616KB
|
211
|
+
active_support/core_ext/time/acts_like 0.0008s 11616KB
|
212
|
+
base64 0.0005s 11768KB
|
213
|
+
bigdecimal 0.0010s 11808KB
|
214
|
+
active_support/multibyte 0.0004s 11812KB
|
215
|
+
active_support/core_ext/string/multibyte 0.0008s 11812KB
|
216
|
+
active_support/inflector/transliterate 0.0086s 11816KB
|
217
|
+
active_support/core_ext/string/inflections 0.0095s 11816KB
|
218
|
+
active_support/core_ext/date_time/calculations 0.0011s 11848KB
|
219
|
+
active_support/core_ext/kernel/reporting 0.0008s 11888KB
|
220
|
+
active_support/core_ext/object/blank 0.0017s 11888KB
|
221
|
+
active_support/xml_mini/rexml 0.0113s 11888KB
|
222
|
+
active_support/xml_mini 0.0429s 11888KB
|
223
|
+
active_support/core_ext/hash/keys 0.0010s 11924KB
|
224
|
+
active_support/core_ext/object/to_query 0.0007s 11924KB
|
225
|
+
active_support/core_ext/object/to_param 0.0011s 11924KB
|
226
|
+
active_support/core_ext/array/conversions 0.0638s 11924KB
|
227
|
+
active_support/core_ext/string/filters 0.0007s 11936KB
|
228
|
+
active_support/duration 0.0740s 11936KB
|
229
|
+
tzinfo/ruby_core_support 0.0009s 12152KB
|
230
|
+
tzinfo/offset_rationals 0.0006s 12196KB
|
231
|
+
tzinfo/time_or_datetime 0.0012s 12224KB
|
232
|
+
tzinfo/timezone_definition 0.0005s 12232KB
|
233
|
+
tzinfo/timezone_offset 0.0006s 12232KB
|
234
|
+
tzinfo/timezone_transition 0.0008s 12288KB
|
235
|
+
tzinfo/timezone_transition_definition 0.0006s 12288KB
|
236
|
+
tzinfo/timezone_index_definition 0.0005s 12288KB
|
237
|
+
tzinfo/timezone_info 0.0004s 12288KB
|
238
|
+
tzinfo/data_timezone_info 0.0005s 12300KB
|
239
|
+
tzinfo/linked_timezone_info 0.0004s 12300KB
|
240
|
+
tzinfo/transition_data_timezone_info 0.0013s 12428KB
|
241
|
+
tzinfo/zoneinfo_timezone_info 0.0014s 12492KB
|
242
|
+
tzinfo/data_source 0.0009s 12532KB
|
243
|
+
tzinfo/ruby_data_source 0.0008s 12548KB
|
244
|
+
tzinfo/zoneinfo_data_source 0.0018s 12636KB
|
245
|
+
tzinfo/timezone_period 0.0009s 12672KB
|
246
|
+
thread_safe/version 0.0004s 12684KB
|
247
|
+
thread_safe/synchronized_delegator 0.0006s 12684KB
|
248
|
+
thread_safe 0.0056s 12684KB
|
249
|
+
thread_safe/non_concurrent_cache_backend 0.0007s 12720KB
|
250
|
+
thread_safe/mri_cache_backend 0.0014s 12720KB
|
251
|
+
thread_safe/cache 0.0026s 12720KB
|
252
|
+
tzinfo/timezone 0.0171s 12720KB
|
253
|
+
tzinfo/info_timezone 0.0005s 12720KB
|
254
|
+
tzinfo/data_timezone 0.0004s 12724KB
|
255
|
+
tzinfo/linked_timezone 0.0005s 12724KB
|
256
|
+
tzinfo/timezone_proxy 0.0006s 12736KB
|
257
|
+
tzinfo/country_index_definition 0.0005s 12740KB
|
258
|
+
tzinfo/country_info 0.0005s 12740KB
|
259
|
+
tzinfo/ruby_country_info 0.0006s 12748KB
|
260
|
+
tzinfo/zoneinfo_country_info 0.0013s 12748KB
|
261
|
+
tzinfo/country 0.0009s 12756KB
|
262
|
+
tzinfo/country_timezone 0.0007s 12760KB
|
263
|
+
tzinfo 0.1486s 12760KB
|
264
|
+
active_support/values/time_zone 0.1584s 12768KB
|
265
|
+
active_support/core_ext/time/conversions 0.1592s 12768KB
|
266
|
+
active_support/time_with_zone 0.0026s 12868KB
|
267
|
+
active_support/core_ext/date_and_time/zones 0.0004s 12868KB
|
268
|
+
active_support/core_ext/time/zones 0.0014s 12868KB
|
269
|
+
active_support/core_ext/object/try 0.0007s 12884KB
|
270
|
+
active_support/core_ext/date_and_time/calculations 0.0023s 12884KB
|
271
|
+
active_support/core_ext/date/zones 0.0005s 12884KB
|
272
|
+
active_support/core_ext/date/calculations 0.0058s 12884KB
|
273
|
+
active_support/core_ext/time/calculations 0.2757s 12884KB
|
274
|
+
active_support/core_ext/module/redefine_method 0.0008s 12884KB
|
275
|
+
active_support/core_ext/time/compatibility 0.0014s 12884KB
|
276
|
+
active_support/core_ext/time 0.2999s 12888KB
|
277
|
+
active_support/core_ext/date/acts_like 0.0004s 12888KB
|
278
|
+
active_support/core_ext/date/blank 0.0004s 12888KB
|
279
|
+
active_support/core_ext/date/conversions 0.0010s 12888KB
|
280
|
+
active_support/core_ext/date 0.0134s 12904KB
|
281
|
+
active_support/core_ext/date_time/acts_like 0.0005s 12904KB
|
282
|
+
active_support/core_ext/date_time/blank 0.0005s 12904KB
|
283
|
+
active_support/core_ext/date_time/compatibility 0.0006s 12908KB
|
284
|
+
active_support/core_ext/date_time/conversions 0.0016s 12936KB
|
285
|
+
active_support/core_ext/date_time 0.0145s 12936KB
|
286
|
+
active_support/core_ext/numeric/time 0.0013s 12980KB
|
287
|
+
active_support/core_ext/integer/time 0.0019s 12980KB
|
288
|
+
active_support/core_ext/string/conversions 0.0011s 13048KB
|
289
|
+
active_support/core_ext/string/zones 0.0005s 13048KB
|
290
|
+
active_support/time 0.3730s 13048KB
|
291
|
+
active_support/core_ext/string/starts_ends_with 0.0004s 13172KB
|
292
|
+
active_support/core_ext/string/access 0.0005s 13172KB
|
293
|
+
active_support/core_ext/string/behavior 0.0009s 13344KB
|
294
|
+
strscan 0.0012s 13912KB
|
295
|
+
erb 0.0054s 13912KB
|
296
|
+
active_support/multibyte/unicode 0.0032s 14188KB
|
297
|
+
active_support/core_ext/string/output_safety 0.0199s 14188KB
|
298
|
+
active_support/core_ext/string/exclude 0.0004s 14192KB
|
299
|
+
active_support/core_ext/string/strip 0.0004s 14196KB
|
300
|
+
active_support/string_inquirer 0.0005s 14224KB
|
301
|
+
active_support/core_ext/string/inquiry 0.0009s 14224KB
|
302
|
+
active_support/core_ext/string/indent 0.0005s 14232KB
|
303
|
+
activesupport-5.2.1/lib/active_support/core_ext/string.rb 0.0599s 14232KB
|
304
|
+
active_support/inflector 0.0007s 14256KB
|
305
|
+
active_support/core_ext/module/introspection 0.0016s 14256KB
|
306
|
+
active_support/core_ext/module/anonymous 0.0006s 14256KB
|
307
|
+
active_support/core_ext/module/reachable 0.0008s 14260KB
|
308
|
+
active_support/core_ext/module/attribute_accessors_per_thread 0.0011s 14284KB
|
309
|
+
active_support/core_ext/module/attr_internal 0.0008s 14296KB
|
310
|
+
active_support/core_ext/module/concerning 0.0007s 14320KB
|
311
|
+
active_support/core_ext/module/remove_method 0.0007s 14324KB
|
312
|
+
activesupport-5.2.1/lib/active_support/core_ext/module.rb 0.0327s 14324KB
|
313
|
+
activesupport-5.2.1/lib/active_support/core_ext/name_error.rb 0.0004s 14360KB
|
314
|
+
active_support/core_ext/array/wrap 0.0004s 14376KB
|
315
|
+
active_support/core_ext/array/access 0.0005s 14400KB
|
316
|
+
active_support/core_ext/array/grouping 0.0006s 14416KB
|
317
|
+
active_support/array_inquirer 0.0005s 14460KB
|
318
|
+
active_support/core_ext/array/inquiry 0.0009s 14460KB
|
319
|
+
activesupport-5.2.1/lib/active_support/core_ext/array.rb 0.0141s 14460KB
|
320
|
+
active_support/core_ext/class/attribute 0.0011s 14516KB
|
321
|
+
active_support/core_ext/class/subclasses 0.0033s 14532KB
|
322
|
+
activesupport-5.2.1/lib/active_support/core_ext/class.rb 0.0083s 14532KB
|
323
|
+
active_support/core_ext/numeric/bytes 0.0005s 14544KB
|
324
|
+
active_support/core_ext/numeric/inquiry 0.0004s 14544KB
|
325
|
+
bigdecimal/util 0.0006s 14552KB
|
326
|
+
active_support/core_ext/big_decimal/conversions 0.0014s 14552KB
|
327
|
+
active_support/number_helper 0.0008s 14552KB
|
328
|
+
active_support/core_ext/numeric/conversions 0.0136s 14552KB
|
329
|
+
activesupport-5.2.1/lib/active_support/core_ext/numeric.rb 0.0220s 14552KB
|
330
|
+
activesupport-5.2.1/lib/active_support/core_ext/load_error.rb 0.0003s 14552KB
|
331
|
+
activesupport-5.2.1/lib/active_support/core_ext/uri.rb 0.0005s 14552KB
|
332
|
+
active_support/core_ext/integer/multiple 0.0004s 14552KB
|
333
|
+
active_support/core_ext/integer/inflections 0.0005s 14556KB
|
334
|
+
activesupport-5.2.1/lib/active_support/core_ext/integer.rb 0.0083s 14556KB
|
335
|
+
active_support/core_ext/hash/compact 0.0004s 14556KB
|
336
|
+
active_support/core_ext/hash/reverse_merge 0.0004s 14556KB
|
337
|
+
active_support/core_ext/hash/conversions 0.0055s 14556KB
|
338
|
+
active_support/hash_with_indifferent_access 0.0014s 14608KB
|
339
|
+
active_support/core_ext/hash/indifferent_access 0.0018s 14608KB
|
340
|
+
active_support/core_ext/hash/transform_values 0.0005s 14612KB
|
341
|
+
activesupport-5.2.1/lib/active_support/core_ext/hash.rb 0.0236s 14612KB
|
342
|
+
fileutils 0.0073s 15424KB
|
343
|
+
active_support/core_ext/file/atomic 0.0079s 15424KB
|
344
|
+
activesupport-5.2.1/lib/active_support/core_ext/file.rb 0.0081s 15424KB
|
345
|
+
active_support/core_ext/range/conversions 0.0004s 15444KB
|
346
|
+
active_support/core_ext/range/include_range 0.0004s 15448KB
|
347
|
+
active_support/core_ext/range/include_time_with_zone 0.0005s 15464KB
|
348
|
+
active_support/core_ext/range/overlaps 0.0004s 15472KB
|
349
|
+
active_support/core_ext/range/each 0.0005s 15476KB
|
350
|
+
activesupport-5.2.1/lib/active_support/core_ext/range.rb 0.0164s 15476KB
|
351
|
+
active_support/core_ext/kernel/agnostics 0.0004s 15488KB
|
352
|
+
active_support/core_ext/kernel/concern 0.0007s 15488KB
|
353
|
+
activesupport-5.2.1/lib/active_support/core_ext/kernel.rb 0.0091s 15492KB
|
354
|
+
benchmark 0.0015s 15572KB
|
355
|
+
activesupport-5.2.1/lib/active_support/core_ext/benchmark.rb 0.0018s 15572KB
|
356
|
+
active_support/core_ext/object/duplicable 0.0010s 15640KB
|
357
|
+
active_support/core_ext/object/deep_dup 0.0006s 15684KB
|
358
|
+
active_support/core_ext/object/inclusion 0.0004s 15688KB
|
359
|
+
active_support/core_ext/object/conversions 0.0007s 15720KB
|
360
|
+
active_support/core_ext/object/instance_variables 0.0004s 15732KB
|
361
|
+
json/version 0.0004s 15968KB
|
362
|
+
ostruct 0.0011s 16076KB
|
363
|
+
json/generic_object 0.0018s 16076KB
|
364
|
+
json/common 0.0079s 16076KB
|
365
|
+
json/ext/parser 0.0007s 16104KB
|
366
|
+
json/ext/generator 0.0008s 16188KB
|
367
|
+
json/ext 0.0061s 16188KB
|
368
|
+
json 0.0249s 16188KB
|
369
|
+
active_support/core_ext/object/json 0.0389s 16196KB
|
370
|
+
active_support/option_merger 0.0008s 16252KB
|
371
|
+
active_support/core_ext/object/with_options 0.0017s 16252KB
|
372
|
+
activesupport-5.2.1/lib/active_support/core_ext/object.rb 0.0667s 16252KB
|
373
|
+
activesupport-5.2.1/lib/active_support/core_ext/marshal.rb 0.0004s 16272KB
|
374
|
+
activesupport-5.2.1/lib/active_support/core_ext/enumerable.rb 0.0009s 16300KB
|
375
|
+
activesupport-5.2.1/lib/active_support/core_ext/securerandom.rb 0.0005s 16332KB
|
376
|
+
activesupport-5.2.1/lib/active_support/core_ext/big_decimal.rb 0.0003s 16348KB
|
377
|
+
active_support/core_ext 0.3828s 16348KB
|
378
|
+
--------------------------------------------------------------------------------------
|
379
|
+
active_support/all 1.4652s 16348KB
|
380
|
+
```
|
381
|
+
|
382
|
+
### archfiend
|
383
|
+
```
|
384
|
+
$ bundle exec analyze_requires archfiend
|
385
|
+
name time RSS after
|
386
|
+
---------------------------------------------------------
|
387
|
+
archfiend/version 0.0010s 1648KB
|
388
|
+
archfiend/application 0.0031s 3024KB
|
389
|
+
logger 0.0071s 4264KB
|
390
|
+
bigdecimal 0.0035s 4668KB
|
391
|
+
oj/version 0.0009s 4700KB
|
392
|
+
oj/bag 0.0010s 4756KB
|
393
|
+
oj/easy_hash 0.0009s 4796KB
|
394
|
+
oj/error 0.0008s 4824KB
|
395
|
+
ostruct 0.0026s 5540KB
|
396
|
+
oj/mimic 0.0048s 5540KB
|
397
|
+
oj/saj 0.0009s 5568KB
|
398
|
+
oj/schandler 0.0008s 5624KB
|
399
|
+
date_core 0.0029s 6096KB
|
400
|
+
oj/oj 0.0139s 6428KB
|
401
|
+
oj 0.0601s 6428KB
|
402
|
+
archfiend/logging 0.0719s 6428KB
|
403
|
+
archfiend/logging/base_formatter 0.0009s 6444KB
|
404
|
+
archfiend/logging/default_formatter 0.0007s 6456KB
|
405
|
+
archfiend/logging/json_formatter 0.0007s 6468KB
|
406
|
+
archfiend/logging/multi_logger 0.0008s 6488KB
|
407
|
+
archfiend/shared_loop/runnable 0.0007s 6488KB
|
408
|
+
archfiend/thread_loop 0.0008s 6528KB
|
409
|
+
archfiend/subprocess_loop 0.0010s 6568KB
|
410
|
+
---------------------------------------------------------
|
411
|
+
archfiend 0.1212s 6568KB
|
412
|
+
```
|
413
|
+
|
414
|
+
## Contributing
|
415
|
+
|
416
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/gem_footprint_analyzer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
417
|
+
|
418
|
+
## License
|
419
|
+
|
420
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
421
|
+
|
422
|
+
## Code of Conduct
|
423
|
+
|
424
|
+
Everyone interacting in the GemFootprintAnalyzer project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/gem_footprint_analyzer/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'gem_footprint_analyzer'
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
options = OpenStruct.new
|
6
|
+
options.runs = 10
|
7
|
+
options.formatter = GemFootprintAnalyzer::TextFormatter
|
8
|
+
|
9
|
+
opts_parser = OptionParser.new do |opts|
|
10
|
+
script_name = "bundle exec #{File.basename($0)}"
|
11
|
+
opts.banner = "Usage: #{script_name} library_to_analyze [require]"
|
12
|
+
|
13
|
+
opts.on('-f', '--formatter FORMATTER', %w[json text], 'Format output using selected formatter') do |formatter|
|
14
|
+
if formatter == 'json'
|
15
|
+
options.formatter = GemFootprintAnalyzer::JsonFormatter
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
opts.on('-n', '--runs-num NUMBER', OptParse::DecimalInteger, 'Number of runs for avergae') do |runs|
|
20
|
+
if runs < 1
|
21
|
+
fail OptionParser::InvalidArgument, 'must be a number greater than 0'
|
22
|
+
end
|
23
|
+
options.runs = runs
|
24
|
+
end
|
25
|
+
|
26
|
+
opts.on_tail('-h', '--help', 'Show this message') do
|
27
|
+
puts opts
|
28
|
+
exit
|
29
|
+
end
|
30
|
+
end
|
31
|
+
opts_parser.parse!(ARGV)
|
32
|
+
|
33
|
+
if ARGV.size < 1
|
34
|
+
puts opts_parser
|
35
|
+
exit 1
|
36
|
+
end
|
37
|
+
|
38
|
+
requires_list_average = GemFootprintAnalyzer::AverageRunner.new(options.runs) do
|
39
|
+
GemFootprintAnalyzer::Analyzer.new.test_library(*ARGV)
|
40
|
+
end.run
|
41
|
+
|
42
|
+
puts options.formatter.new.format(requires_list_average)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "gem_footprint_analyzer/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "gem_footprint_analyzer"
|
8
|
+
spec.version = GemFootprintAnalyzer::VERSION
|
9
|
+
spec.authors = ["Maciek Dubiński"]
|
10
|
+
spec.email = ["maciek@dubinski.net"]
|
11
|
+
|
12
|
+
spec.summary = %q{A simple tool to analyze footprint of Ruby requires.}
|
13
|
+
spec.homepage = "https://github.com/irvingwashington/gem_footprint_analyzer"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
# Specify which files should be added to the gem when it is released.
|
17
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
18
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
19
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
|
+
end
|
21
|
+
spec.bindir = "exe"
|
22
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
|
+
spec.require_paths = ["lib"]
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
28
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'gem_footprint_analyzer/version'
|
2
|
+
require 'gem_footprint_analyzer/pipe_transport'
|
3
|
+
require 'gem_footprint_analyzer/require_spy'
|
4
|
+
require 'gem_footprint_analyzer/analyzer'
|
5
|
+
require 'gem_footprint_analyzer/text_formatter'
|
6
|
+
require 'gem_footprint_analyzer/json_formatter'
|
7
|
+
require 'gem_footprint_analyzer/average_runner'
|
8
|
+
|
9
|
+
module GemFootprintAnalyzer
|
10
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module GemFootprintAnalyzer
|
2
|
+
class Analyzer
|
3
|
+
|
4
|
+
def test_library(library, require_string=nil)
|
5
|
+
try_activate_gem(library)
|
6
|
+
|
7
|
+
child_transport, parent_transport = init_transports
|
8
|
+
|
9
|
+
process_id = fork_and_require(require_string || library, child_transport)
|
10
|
+
requires = collect_requires(parent_transport, process_id)
|
11
|
+
|
12
|
+
parent_transport.ack
|
13
|
+
requires
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def fork_and_require(require_string, child_transport)
|
19
|
+
GC.start
|
20
|
+
process_id = fork do
|
21
|
+
RequireSpy.spy_require(child_transport)
|
22
|
+
begin
|
23
|
+
require(require_string)
|
24
|
+
rescue LoadError => e
|
25
|
+
child_transport.exit_with_error(e)
|
26
|
+
exit
|
27
|
+
end
|
28
|
+
child_transport.done
|
29
|
+
child_transport.wait_for_ack
|
30
|
+
end
|
31
|
+
Process.detach(process_id)
|
32
|
+
process_id
|
33
|
+
end
|
34
|
+
|
35
|
+
def collect_requires(parent_transport, process_id)
|
36
|
+
base_rss = nil
|
37
|
+
requires = []
|
38
|
+
while (msg, payload = parent_transport.read_one_command)
|
39
|
+
if msg == :require
|
40
|
+
curr_rss = rss(process_id)
|
41
|
+
name, time = payload
|
42
|
+
requires << {name: name, time: Float(time) * 1000, rss: curr_rss - base_rss}
|
43
|
+
elsif msg == :already_required
|
44
|
+
elsif msg == :ready
|
45
|
+
unless base_rss
|
46
|
+
base_rss = rss(process_id)
|
47
|
+
requires << {base: true, rss: base_rss}
|
48
|
+
end
|
49
|
+
parent_transport.start
|
50
|
+
elsif msg == :exit
|
51
|
+
puts "Exiting because of exception: #{payload}"
|
52
|
+
exit 1
|
53
|
+
elsif msg == :done
|
54
|
+
break
|
55
|
+
end
|
56
|
+
end
|
57
|
+
requires
|
58
|
+
end
|
59
|
+
|
60
|
+
def try_activate_gem(library)
|
61
|
+
gem(library)
|
62
|
+
rescue Gem::LoadError
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def pkill(process_id)
|
67
|
+
Process.kill('TERM', process_id)
|
68
|
+
end
|
69
|
+
|
70
|
+
def rss(process_id)
|
71
|
+
`ps -o rss -p #{process_id}`.split.last.strip.to_i
|
72
|
+
end
|
73
|
+
|
74
|
+
def init_transports
|
75
|
+
child_reader, parent_writer = IO.pipe
|
76
|
+
parent_reader, child_writer = IO.pipe
|
77
|
+
|
78
|
+
child_transport = GemFootprintAnalyzer::PipeTransport.new(child_reader, child_writer)
|
79
|
+
parent_transport = GemFootprintAnalyzer::PipeTransport.new(parent_reader, parent_writer)
|
80
|
+
|
81
|
+
[child_transport, parent_transport]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module GemFootprintAnalyzer
|
2
|
+
class AverageRunner
|
3
|
+
RUNS = 10
|
4
|
+
AVERAGED_FIELDS = %i[rss time]
|
5
|
+
|
6
|
+
def initialize(runs=RUNS, &run_block)
|
7
|
+
fail ArgumentError, 'runs must be > 0' if runs < 1
|
8
|
+
|
9
|
+
@run_block = run_block
|
10
|
+
@runs = runs
|
11
|
+
end
|
12
|
+
|
13
|
+
def run
|
14
|
+
results = []
|
15
|
+
@runs.times do
|
16
|
+
results << run_once
|
17
|
+
end
|
18
|
+
calculate_averages(results)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def run_once
|
24
|
+
@run_block.call
|
25
|
+
end
|
26
|
+
|
27
|
+
# Take corresponding results array values and compare them
|
28
|
+
def calculate_averages(results)
|
29
|
+
average_results = []
|
30
|
+
first_run = results[0]
|
31
|
+
|
32
|
+
first_run.size.times do |require_number|
|
33
|
+
samples = results.map { |r| r[require_number] }
|
34
|
+
first_sample = samples.first
|
35
|
+
|
36
|
+
average = initialize_average_with_copied_fields(first_sample)
|
37
|
+
AVERAGED_FIELDS.map do |field|
|
38
|
+
next unless first_sample.key?(field)
|
39
|
+
|
40
|
+
average[field] = calculate_average(samples.map { |s| s[field] })
|
41
|
+
end
|
42
|
+
average_results << average
|
43
|
+
end
|
44
|
+
average_results
|
45
|
+
end
|
46
|
+
|
47
|
+
def calculate_average(values)
|
48
|
+
num = values.size
|
49
|
+
sum = values.sum.to_f
|
50
|
+
mean = sum / num
|
51
|
+
|
52
|
+
stddev = Math.sqrt(values.sum { |v| (v - mean) ** 2 } / num)
|
53
|
+
{mean: mean, sttdev: stddev}
|
54
|
+
end
|
55
|
+
|
56
|
+
def initialize_average_with_copied_fields(sample)
|
57
|
+
average = {}
|
58
|
+
(sample.keys - AVERAGED_FIELDS).each { |k| average[k] = sample[k] }
|
59
|
+
average
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module GemFootprintAnalyzer
|
2
|
+
class PipeTransport
|
3
|
+
def initialize(read_stream, write_stream)
|
4
|
+
@read_stream = read_stream
|
5
|
+
@write_stream = write_stream
|
6
|
+
end
|
7
|
+
|
8
|
+
def read_one_command
|
9
|
+
str = @read_stream.gets.strip
|
10
|
+
|
11
|
+
case str
|
12
|
+
when /\Adone\z/
|
13
|
+
[:done, nil]
|
14
|
+
when /\Aack\z/
|
15
|
+
[:ack, nil]
|
16
|
+
when /\Arq: "([^"]+)",(.+)\z/
|
17
|
+
[:require, [$1, $2]]
|
18
|
+
when /\Aarq: "([^"]+)"\z/
|
19
|
+
[:already_required, $1]
|
20
|
+
when /\Astart\z/
|
21
|
+
[:start, nil]
|
22
|
+
when /\Aready\z/
|
23
|
+
[:ready, nil]
|
24
|
+
when /\Aexit: "([^"]+)"\z/
|
25
|
+
[:exit, $1]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def wait_for_start
|
30
|
+
while (msg, payload = read_one_command)
|
31
|
+
break if msg == :start
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def wait_for_ack
|
36
|
+
while (msg, data = read_one_command)
|
37
|
+
break if msg == :ack
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def ready
|
42
|
+
@write_stream.puts 'ready'
|
43
|
+
end
|
44
|
+
|
45
|
+
def start
|
46
|
+
@write_stream.puts 'start'
|
47
|
+
end
|
48
|
+
|
49
|
+
def ack
|
50
|
+
@write_stream.puts 'ack'
|
51
|
+
end
|
52
|
+
|
53
|
+
# Signalize finalization
|
54
|
+
def done
|
55
|
+
@write_stream.puts 'done'
|
56
|
+
end
|
57
|
+
|
58
|
+
def report_require(library, duration)
|
59
|
+
@write_stream.puts "rq: #{library.inspect},#{duration.inspect}"
|
60
|
+
end
|
61
|
+
|
62
|
+
def report_already_required(library)
|
63
|
+
@write_stream.puts "arq: #{library.inspect}"
|
64
|
+
end
|
65
|
+
|
66
|
+
def exit_with_error(e)
|
67
|
+
@write_stream.puts "exit: #{e.to_s.inspect}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module GemFootprintAnalyzer
|
2
|
+
module RequireSpy
|
3
|
+
def self.spy_require(interactor)
|
4
|
+
Kernel.alias_method :regular_require, :require
|
5
|
+
|
6
|
+
Kernel.define_method :timed_exec do |&block|
|
7
|
+
start_time = Time.now.to_f
|
8
|
+
block.call
|
9
|
+
(Time.now.to_f - start_time).round(4)
|
10
|
+
end
|
11
|
+
|
12
|
+
Kernel.define_method :require do |name|
|
13
|
+
result = nil
|
14
|
+
|
15
|
+
interactor.ready
|
16
|
+
interactor.wait_for_start
|
17
|
+
|
18
|
+
t = timed_exec do
|
19
|
+
result = regular_require(name)
|
20
|
+
end
|
21
|
+
|
22
|
+
if result
|
23
|
+
interactor.report_require(name, t)
|
24
|
+
else
|
25
|
+
interactor.report_already_required(name)
|
26
|
+
end
|
27
|
+
result
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module GemFootprintAnalyzer
|
2
|
+
class TextFormatter
|
3
|
+
TABULATION = ' '.freeze
|
4
|
+
NEWLINE = "\n".freeze
|
5
|
+
|
6
|
+
def format(requires_list)
|
7
|
+
return if requires_list.size == 1
|
8
|
+
entries_num = requires_list.size
|
9
|
+
lines = []
|
10
|
+
longest_name_length = requires_list.map { |el| el[:name]&.length }.compact.max
|
11
|
+
|
12
|
+
lines << [format_name('name', longest_name_length, false), ' time ', 'RSS after'].join(' ')
|
13
|
+
lines << dash(longest_name_length) if requires_list.size > 2
|
14
|
+
|
15
|
+
requires_list.each_with_index do |entry, i|
|
16
|
+
next if i.zero?
|
17
|
+
|
18
|
+
last_element = (i == entries_num - 1)
|
19
|
+
|
20
|
+
name, time, rss = entry.values_at(:name, :time, :rss)
|
21
|
+
lines << dash(longest_name_length) if last_element
|
22
|
+
lines << [format_name(name, longest_name_length, last_element), format_time(time), format_rss(rss)].join(' ')
|
23
|
+
end
|
24
|
+
lines.join(NEWLINE)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def format_name(name, longest_name_length, last_element = false)
|
30
|
+
left_just_size = longest_name_length + 3
|
31
|
+
left_just_size += TABULATION.size if last_element
|
32
|
+
tabulation = last_element ? '' : TABULATION
|
33
|
+
tabulation + name.ljust(left_just_size)
|
34
|
+
end
|
35
|
+
|
36
|
+
def format_time(time)
|
37
|
+
value = time.is_a?(Hash) ? time[:mean] : time
|
38
|
+
"%4dms" % value.round
|
39
|
+
end
|
40
|
+
|
41
|
+
def format_rss(rss)
|
42
|
+
value = rss.is_a?(Hash) ? rss[:mean] : rss
|
43
|
+
"%6dKB" % value
|
44
|
+
end
|
45
|
+
|
46
|
+
def dash(longest_name_length)
|
47
|
+
'-' * (longest_name_length + 22)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gem_footprint_analyzer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Maciek Dubiński
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-10-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.16'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.16'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
description:
|
56
|
+
email:
|
57
|
+
- maciek@dubinski.net
|
58
|
+
executables:
|
59
|
+
- analyze_requires
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
64
|
+
- ".rspec"
|
65
|
+
- ".travis.yml"
|
66
|
+
- CODE_OF_CONDUCT.md
|
67
|
+
- Gemfile
|
68
|
+
- LICENSE.txt
|
69
|
+
- README.md
|
70
|
+
- Rakefile
|
71
|
+
- exe/analyze_requires
|
72
|
+
- gem_footprint_analyzer.gemspec
|
73
|
+
- lib/gem_footprint_analyzer.rb
|
74
|
+
- lib/gem_footprint_analyzer/analyzer.rb
|
75
|
+
- lib/gem_footprint_analyzer/average_runner.rb
|
76
|
+
- lib/gem_footprint_analyzer/json_formatter.rb
|
77
|
+
- lib/gem_footprint_analyzer/pipe_transport.rb
|
78
|
+
- lib/gem_footprint_analyzer/require_spy.rb
|
79
|
+
- lib/gem_footprint_analyzer/text_formatter.rb
|
80
|
+
- lib/gem_footprint_analyzer/version.rb
|
81
|
+
homepage: https://github.com/irvingwashington/gem_footprint_analyzer
|
82
|
+
licenses:
|
83
|
+
- MIT
|
84
|
+
metadata: {}
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 2.7.6
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: A simple tool to analyze footprint of Ruby requires.
|
105
|
+
test_files: []
|