allocation_stats 0.1.3 → 0.1.4
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/.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 [](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
|