allocation_stats 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.markdown +8 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +2 -0
- data/README.markdown +29 -19
- data/allocation_stats.gemspec +3 -5
- data/lib/allocation_stats/allocation.rb +2 -2
- data/lib/allocation_stats/allocations_proxy.rb +12 -0
- data/spec/allocation_stats/allocations_proxy_spec.rb +14 -5
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 67f90cfc4c5d04fb2be23255b4194c037a506ef4
|
4
|
+
data.tar.gz: 35c20f3a4e115f097f079c9f2c71e60eeadbf49a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a7d4b6a68b4ef81ba559f87b1cf2eeca88548f294a06f53423e2839049cb5c609e23e956665a1025057c07d66d5604619f4aacd041f4b13d4a174f82febd169
|
7
|
+
data.tar.gz: 17d1f24af19d8668461b4d1d31bf7b24ac84b18986c26f3566056524e1bf1affdf5d7061cdd40e2ccfdae126661a02cc96c9dc6bc54457f7de47c873e126a7ea
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/CHANGELOG.markdown
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
v0.1.4
|
2
|
+
|
3
|
+
* Added: Build status now tracked with Travis
|
4
|
+
* Fixed: Working... better? with new frozen String keys
|
5
|
+
* Fixed: alias order changed so that PWD is searched after GEMDIR and
|
6
|
+
RUBYLIBDIR, in case of vendored bundler directory.
|
7
|
+
* Added: `at_least` method for the AllocationsProxy, tested and documented
|
8
|
+
|
1
9
|
v0.1.3
|
2
10
|
|
3
11
|
* Fixed: BasicObjects can be tracked; fixes #1
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -10,6 +10,7 @@ GEM
|
|
10
10
|
coderay (~> 1.0.5)
|
11
11
|
method_source (~> 0.8)
|
12
12
|
slop (~> 3.4)
|
13
|
+
rake (10.1.0)
|
13
14
|
rspec (2.13.0)
|
14
15
|
rspec-core (~> 2.13.0)
|
15
16
|
rspec-expectations (~> 2.13.0)
|
@@ -32,6 +33,7 @@ PLATFORMS
|
|
32
33
|
|
33
34
|
DEPENDENCIES
|
34
35
|
pry
|
36
|
+
rake
|
35
37
|
rspec
|
36
38
|
simplecov
|
37
39
|
yajl-ruby (= 1.1.0)
|
data/README.markdown
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
AllocationStats [![Build Status](https://travis-ci.org/srawlins/allocation_stats.png?branch=master)](https://travis-ci.org/srawlins/allocation_stats)
|
2
|
+
===============
|
3
|
+
|
1
4
|
Introduction
|
2
|
-
|
5
|
+
------------
|
3
6
|
|
4
7
|
AllocationStats is a rubygem that makes use of Ruby 2.1's new abilities to trace
|
5
8
|
Ruby object allocations (MRI only). Ruby 2.1's new
|
@@ -11,8 +14,21 @@ AllocationStats collects all of the allocation information generated by
|
|
11
14
|
`ObjectSpace.trace_object_allocations`, then provides mechanisms for filtering,
|
12
15
|
grouping, and sorting the allocation information.
|
13
16
|
|
14
|
-
|
15
|
-
|
17
|
+
### Install
|
18
|
+
|
19
|
+
To install AllocationStats, add the following line to a project's Gemfile, perhaps to the development group:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem 'allocation_stats'
|
23
|
+
```
|
24
|
+
|
25
|
+
or run the following command:
|
26
|
+
|
27
|
+
```shell
|
28
|
+
gem install allocation_stats
|
29
|
+
```
|
30
|
+
|
31
|
+
### Tabular Output examples
|
16
32
|
|
17
33
|
It is very easy to get some simple statistics out of AllocationStats.
|
18
34
|
Wrap some code with `AllocationStats.trace` and print out a listing of all of the
|
@@ -69,8 +85,7 @@ puts stats.allocations(alias_paths: true).group_by(:sourcefile, :sourceline, :cl
|
|
69
85
|
(This full example is found in `examples/trace_my_class_group_by.rb`)
|
70
86
|
|
71
87
|
|
72
|
-
More on `trace_object_allocations()`
|
73
|
-
---------------------------------------------
|
88
|
+
### More on `trace_object_allocations()`
|
74
89
|
|
75
90
|
To start at the beginning: Ruby 2.1 will be released with a new feature that
|
76
91
|
enables one to trace object allocations. Through
|
@@ -99,8 +114,7 @@ allocations.rb
|
|
99
114
|
4
|
100
115
|
```
|
101
116
|
|
102
|
-
Example from the specs
|
103
|
-
----------------------
|
117
|
+
### Example from the specs
|
104
118
|
|
105
119
|
```ruby
|
106
120
|
existing_array = [1,2,3,4,5]
|
@@ -177,8 +191,7 @@ You can see that there are three different groups:
|
|
177
191
|
Only one allocation belongs to each of the first two groups, and two allocations
|
178
192
|
make up the second group.
|
179
193
|
|
180
|
-
A little slower
|
181
|
-
---------------
|
194
|
+
### A little slower
|
182
195
|
|
183
196
|
Let's look at this example a little slower. Firstly, let's look at how we
|
184
197
|
collect object allocations using AllocationStats:
|
@@ -213,8 +226,7 @@ AllocationsProxy object back, so that transformations can be chained. The final
|
|
213
226
|
call that will execute the transformations is `#to_a` (aliased to `#all`, just
|
214
227
|
like ActiveRecord).
|
215
228
|
|
216
|
-
Psych Example
|
217
|
-
-------------
|
229
|
+
### Psych Example
|
218
230
|
|
219
231
|
Let's look at an example with more varied allocations, using Ruby's Psych. This
|
220
232
|
one is found in `examples/trace_psych_keys.rb`:
|
@@ -312,8 +324,7 @@ puts stats.allocations(alias_paths: true).group_by(:sourcefile, :class).to_text
|
|
312
324
|
<RUBYLIBDIR>/psych/scalar_scanner.rb MatchData 2
|
313
325
|
```
|
314
326
|
|
315
|
-
Burn One
|
316
|
-
========
|
327
|
+
### Burn One
|
317
328
|
|
318
329
|
If you find a lot of allocations in `kernel_require.rb` or a lot of allocations
|
319
330
|
of `RubyVM::InstructuinSequences`, you can "burn" one or more calls to your
|
@@ -323,7 +334,7 @@ without tracing allocations, before calling the block a 4th time, tracing
|
|
323
334
|
allocations.
|
324
335
|
|
325
336
|
The API
|
326
|
-
|
337
|
+
-------
|
327
338
|
|
328
339
|
So what methods are available on that AllocationsProxy thing? So far, the API
|
329
340
|
consists of:
|
@@ -346,10 +357,10 @@ consists of:
|
|
346
357
|
```ruby
|
347
358
|
allocations.where(class: Array, size: ->(size) { size > 10 }
|
348
359
|
```
|
360
|
+
* `#at_least(n)` selects allocation groups with at least `n` allocations per group.
|
349
361
|
* `#bytes`, which has an inconsistent definition, I think... TODO
|
350
362
|
|
351
|
-
What are faux attributes?
|
352
|
-
-------------------------
|
363
|
+
### What are faux attributes?
|
353
364
|
|
354
365
|
Valid values for `#group_by` and `#where` include:
|
355
366
|
* instance variables on each `Allocation`. These include `:sourcefile`,
|
@@ -362,11 +373,10 @@ Valid values for `#group_by` and `#where` include:
|
|
362
373
|
|
363
374
|
I'm calling these things that you can group by or filter by, "faux attributes."
|
364
375
|
|
365
|
-
What is `class_plus`?
|
366
|
-
---------------------
|
376
|
+
### What is `class_plus`?
|
367
377
|
|
368
378
|
References
|
369
|
-
|
379
|
+
----------
|
370
380
|
|
371
381
|
This new feature was inspired by work that @tmm1 did at GitHub, as
|
372
382
|
described in
|
data/allocation_stats.gemspec
CHANGED
@@ -3,20 +3,18 @@
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |spec|
|
5
5
|
spec.name = "allocation_stats"
|
6
|
-
spec.version = "0.1.
|
6
|
+
spec.version = "0.1.4"
|
7
7
|
spec.authors = ["Sam Rawlins"]
|
8
8
|
spec.email = ["sam.rawlins@gmail.com"]
|
9
9
|
spec.homepage = "https://github.com/srawlins/allocation_stats"
|
10
10
|
spec.license = "Apache v2"
|
11
11
|
spec.summary = "Tooling for tracing object allocations in Ruby 2.1"
|
12
|
-
spec.description = "Tooling for tracing object allocations in Ruby 2.1
|
13
|
-
"aggregate information about object allocations; group, " +
|
14
|
-
"sort, and filter allocation information."
|
12
|
+
spec.description = "Tooling for tracing object allocations in Ruby 2.1"
|
15
13
|
|
16
14
|
spec.files = `git ls-files`.split("\n")
|
17
15
|
spec.require_paths = ["lib"]
|
18
16
|
|
19
|
-
spec.add_development_dependency "rspec"
|
17
|
+
spec.add_development_dependency "rspec"
|
20
18
|
|
21
19
|
# ">= 2.1.0" seems logical, but rubygems thought that "2.1.0.dev.0" did not fit that bill.
|
22
20
|
# "> 2.0.0" was my next guess, but apparently "2.0.0.247" _does_ fit that bill.
|
@@ -59,12 +59,12 @@ class AllocationStats
|
|
59
59
|
# @return the source file, aliased.
|
60
60
|
def sourcefile_alias
|
61
61
|
case
|
62
|
-
when @sourcefile[PWD]
|
63
|
-
@sourcefile.sub(PWD, "<PWD>")
|
64
62
|
when @sourcefile[AllocationStats::RUBYLIBDIR]
|
65
63
|
@sourcefile.sub(AllocationStats::RUBYLIBDIR, "<RUBYLIBDIR>")
|
66
64
|
when @sourcefile[AllocationStats::GEMDIR]
|
67
65
|
@sourcefile.sub(/#{AllocationStats::GEMDIR}\/gems\/([^\/]+)\//, '<GEM:\1>/')
|
66
|
+
when @sourcefile[PWD]
|
67
|
+
@sourcefile.sub(PWD, "<PWD>")
|
68
68
|
else
|
69
69
|
@sourcefile
|
70
70
|
end
|
@@ -94,6 +94,18 @@ class AllocationStats
|
|
94
94
|
end
|
95
95
|
alias :sort_by_count :sort_by_size
|
96
96
|
|
97
|
+
# Select allocation groups which have at least `count` allocations.
|
98
|
+
#
|
99
|
+
# @param [Fixnum] count the minimum number of Allocations for each group to
|
100
|
+
# be selected.
|
101
|
+
def at_least(count)
|
102
|
+
@mappers << Proc.new do |allocations|
|
103
|
+
allocations.delete_if { |key,value| value.size < count }
|
104
|
+
end
|
105
|
+
|
106
|
+
self
|
107
|
+
end
|
108
|
+
|
97
109
|
# Select allocations for which the {Allocation#sourcefile sourcefile}
|
98
110
|
# includes `pattern`.
|
99
111
|
#
|
@@ -268,8 +268,8 @@ describe AllocationStats::AllocationsProxy do
|
|
268
268
|
text = @stats.allocations.to_text
|
269
269
|
spec_helper_plus_line = "#{SPEC_HELPER_PATH.ljust(MAX_PATH_LENGTH)} #{MyClass::MY_METHOD_BODY_LINE}"
|
270
270
|
|
271
|
-
expect(text).to include("
|
272
|
-
expect(text).to include("
|
271
|
+
expect(text).to include("#{"sourcefile".center(MAX_PATH_LENGTH)} sourceline class_path method_id memsize class")
|
272
|
+
expect(text).to include("#{"-" * MAX_PATH_LENGTH} ---------- ---------- --------- ------- -------")
|
273
273
|
expect(text).to include("#{spec_helper_plus_line} MyClass my_method 192 Hash")
|
274
274
|
expect(text).to include("#{spec_helper_plus_line} MyClass my_method 0 String")
|
275
275
|
expect(text).to include("#{__FILE__.ljust(MAX_PATH_LENGTH)} #{@line} Class new 0 MyClass")
|
@@ -279,7 +279,7 @@ describe AllocationStats::AllocationsProxy do
|
|
279
279
|
text = @stats.allocations.to_text(columns: [:sourcefile, :sourceline, :class])
|
280
280
|
spec_helper_plus_line = "#{SPEC_HELPER_PATH.ljust(MAX_PATH_LENGTH)} #{MyClass::MY_METHOD_BODY_LINE}"
|
281
281
|
|
282
|
-
expect(text).to include("
|
282
|
+
expect(text).to include("#{"sourcefile".center(MAX_PATH_LENGTH)} sourceline class")
|
283
283
|
expect(text).to include("#{"-" * MAX_PATH_LENGTH} ---------- -------")
|
284
284
|
expect(text).to include("#{spec_helper_plus_line} Hash")
|
285
285
|
expect(text).to include("#{spec_helper_plus_line} String")
|
@@ -327,7 +327,7 @@ describe AllocationStats::AllocationsProxy do
|
|
327
327
|
|
328
328
|
first = {
|
329
329
|
"file" => "<PWD>/spec/spec_helper.rb",
|
330
|
-
"file (raw)" => "/
|
330
|
+
"file (raw)" => "#{Dir.pwd}/spec/spec_helper.rb",
|
331
331
|
"line" => 23,
|
332
332
|
"class_path" => "MyClass",
|
333
333
|
"method_id" => :my_method.to_s,
|
@@ -365,7 +365,16 @@ describe AllocationStats::AllocationsProxy do
|
|
365
365
|
expect(results.values[2].size).to eq(1)
|
366
366
|
end
|
367
367
|
|
368
|
-
it "should
|
368
|
+
it "should filter out low count Allocations" do
|
369
|
+
results = @stats.allocations.group_by(:sourcefile, :sourceline, :class).at_least(4).all
|
370
|
+
|
371
|
+
expect(results.size).to eq(1)
|
372
|
+
|
373
|
+
expect(results.keys[0]).to include(@lines[1])
|
374
|
+
expect(results.values[0].size).to eq(4)
|
375
|
+
end
|
376
|
+
|
377
|
+
it "should output to fixed-width text after group_by(...).sort_by_count correctly" do
|
369
378
|
text = @stats.allocations(alias_paths: true)
|
370
379
|
.group_by(:sourcefile, :sourceline, :class)
|
371
380
|
.sort_by_count
|
metadata
CHANGED
@@ -1,31 +1,30 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: allocation_stats
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Rawlins
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-02-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
27
|
-
description: Tooling for tracing object allocations in Ruby 2.1
|
28
|
-
about object allocations; group, sort, and filter allocation information.
|
26
|
+
version: '0'
|
27
|
+
description: Tooling for tracing object allocations in Ruby 2.1
|
29
28
|
email:
|
30
29
|
- sam.rawlins@gmail.com
|
31
30
|
executables: []
|
@@ -33,6 +32,7 @@ extensions: []
|
|
33
32
|
extra_rdoc_files: []
|
34
33
|
files:
|
35
34
|
- ".gitignore"
|
35
|
+
- ".travis.yml"
|
36
36
|
- ".yardopts"
|
37
37
|
- CHANGELOG.markdown
|
38
38
|
- Gemfile
|
@@ -76,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
76
|
version: '0'
|
77
77
|
requirements: []
|
78
78
|
rubyforge_project:
|
79
|
-
rubygems_version: 2.2.0
|
79
|
+
rubygems_version: 2.2.0
|
80
80
|
signing_key:
|
81
81
|
specification_version: 4
|
82
82
|
summary: Tooling for tracing object allocations in Ruby 2.1
|