allocation_sampler 1.0.0 → 1.0.1
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 +4 -0
- data/Gemfile +7 -0
- data/Rakefile +11 -23
- data/allocation_sampler.gemspec +19 -0
- data/ext/allocation_sampler/allocation_sampler.c +3 -3
- data/lib/allocation_sampler/version.rb +5 -0
- data/lib/allocation_sampler.rb +1 -0
- metadata +14 -68
- data/test/test_allocation_sampler.rb +0 -170
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb7006e8c5aba01f01ff5e87c86cc275c65b02492cad740ba729f04bb1adba63
|
4
|
+
data.tar.gz: 85b62b5b5f664430b3f7069f3f389ac5f951578d9f395fd9ac6c902150dc2fb5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb6ac8eee050569271aceaf843a73ef18537947db7dd3d043e701401e411f4d0198d2e9499767d4865826898b9a2fd57e5442c0fc584424e8f173921abddec62
|
7
|
+
data.tar.gz: 0cafcb0e4498b40d5a7c4c994714063483d2b40501e39c42750c8431ef66403552d6a4e5858ec2ab546437e4df4f100b2d5a934b266f529d54e57a60877670c7
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
CHANGED
@@ -1,26 +1,14 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
HOE = Hoe.spec 'allocation_sampler' do
|
12
|
-
developer('Aaron Patterson', 'aaron@tenderlovemaking.com')
|
13
|
-
self.readme_file = 'README.md'
|
14
|
-
self.history_file = 'CHANGELOG.md'
|
15
|
-
self.extra_rdoc_files = FileList['*.md']
|
16
|
-
self.license 'MIT'
|
17
|
-
self.spec_extras = {
|
18
|
-
:extensions => ["ext/allocation_sampler/extconf.rb"],
|
19
|
-
}
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
require "rake/testtask"
|
4
|
+
require "rake/extensiontask"
|
5
|
+
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
7
|
+
t.libs << "test"
|
8
|
+
t.libs << "lib"
|
9
|
+
t.test_files = FileList["test/**/test_*.rb"]
|
20
10
|
end
|
21
11
|
|
22
|
-
Rake::ExtensionTask.new("allocation_sampler"
|
23
|
-
|
24
|
-
task :default => [:compile, :test]
|
12
|
+
Rake::ExtensionTask.new("allocation_sampler")
|
25
13
|
|
26
|
-
|
14
|
+
task default: %i(compile test)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/allocation_sampler/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = %q{allocation_sampler}
|
7
|
+
s.version = ObjectSpace::AllocationSampler::VERSION
|
8
|
+
s.authors = ['Aaron Patterson']
|
9
|
+
s.email = ['aaron@tenderlovemaking.com']
|
10
|
+
s.summary = 'A sampling allocation profiler.'
|
11
|
+
s.description = "This keeps track of allocations, but only onspecified intervals. Useful for profiling allocations in programs where there is a time limit on completion of the program."
|
12
|
+
s.extensions = %w(ext/allocation_sampler/extconf.rb)
|
13
|
+
s.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
14
|
+
%x(git ls-files -z).split("\x0").reject { |f| f.match(%r{^(test|spec|features|bin|\.)/}) }
|
15
|
+
end
|
16
|
+
|
17
|
+
s.homepage = 'https://github.com/tenderlove/allocation_sampler'
|
18
|
+
s.licenses = ['MIT']
|
19
|
+
end
|
@@ -105,7 +105,7 @@ make_frame_info(VALUE *frames, int *lines)
|
|
105
105
|
|
106
106
|
for(i = 0; i < count; i++, frames++, lines++) {
|
107
107
|
VALUE line = INT2NUM(*lines);
|
108
|
-
rb_ary_push(rb_frames, rb_ary_new3(2,
|
108
|
+
rb_ary_push(rb_frames, rb_ary_new3(2, ULL2NUM(*frames), line));
|
109
109
|
}
|
110
110
|
|
111
111
|
return rb_frames;
|
@@ -370,13 +370,13 @@ frames(VALUE self)
|
|
370
370
|
|
371
371
|
VALUE args[3];
|
372
372
|
|
373
|
-
args[0] =
|
373
|
+
args[0] = ULL2NUM(*head);
|
374
374
|
args[1] = rb_profile_frame_full_label(*head);
|
375
375
|
args[2] = file;
|
376
376
|
|
377
377
|
frame = rb_class_new_instance(3, args, rb_cFrame);
|
378
378
|
|
379
|
-
rb_hash_aset(frames,
|
379
|
+
rb_hash_aset(frames, ULL2NUM(*head), frame);
|
380
380
|
|
381
381
|
/* Skip duplicates */
|
382
382
|
VALUE *cmp;
|
data/lib/allocation_sampler.rb
CHANGED
metadata
CHANGED
@@ -1,94 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: allocation_sampler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Patterson
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '5.11'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '5.11'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rdoc
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '4.0'
|
34
|
-
- - "<"
|
35
|
-
- !ruby/object:Gem::Version
|
36
|
-
version: '7'
|
37
|
-
type: :development
|
38
|
-
prerelease: false
|
39
|
-
version_requirements: !ruby/object:Gem::Requirement
|
40
|
-
requirements:
|
41
|
-
- - ">="
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
version: '4.0'
|
44
|
-
- - "<"
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version: '7'
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: hoe
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
50
|
-
requirements:
|
51
|
-
- - "~>"
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '3.17'
|
54
|
-
type: :development
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
requirements:
|
58
|
-
- - "~>"
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version: '3.17'
|
61
|
-
description: |-
|
62
|
-
A sampling allocation profiler. This keeps track of allocations, but only on
|
63
|
-
specified intervals. Useful for profiling allocations in programs where there
|
64
|
-
is a time limit on completion of the program.
|
10
|
+
date: 2025-06-11 00:00:00.000000000 Z
|
11
|
+
dependencies: []
|
12
|
+
description: This keeps track of allocations, but only onspecified intervals. Useful
|
13
|
+
for profiling allocations in programs where there is a time limit on completion
|
14
|
+
of the program.
|
65
15
|
email:
|
66
16
|
- aaron@tenderlovemaking.com
|
67
17
|
executables: []
|
68
18
|
extensions:
|
69
19
|
- ext/allocation_sampler/extconf.rb
|
70
|
-
extra_rdoc_files:
|
71
|
-
- CHANGELOG.md
|
72
|
-
- Manifest.txt
|
73
|
-
- README.md
|
20
|
+
extra_rdoc_files: []
|
74
21
|
files:
|
22
|
+
- ".gitignore"
|
75
23
|
- CHANGELOG.md
|
24
|
+
- Gemfile
|
76
25
|
- Manifest.txt
|
77
26
|
- README.md
|
78
27
|
- Rakefile
|
28
|
+
- allocation_sampler.gemspec
|
79
29
|
- ext/allocation_sampler/allocation_sampler.c
|
80
30
|
- ext/allocation_sampler/extconf.rb
|
81
31
|
- ext/allocation_sampler/sort_r.h
|
82
32
|
- lib/allocation_sampler.rb
|
83
|
-
-
|
33
|
+
- lib/allocation_sampler/version.rb
|
84
34
|
homepage: https://github.com/tenderlove/allocation_sampler
|
85
35
|
licenses:
|
86
36
|
- MIT
|
87
37
|
metadata: {}
|
88
|
-
|
89
|
-
rdoc_options:
|
90
|
-
- "--main"
|
91
|
-
- README.md
|
38
|
+
rdoc_options: []
|
92
39
|
require_paths:
|
93
40
|
- lib
|
94
41
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -102,8 +49,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
102
49
|
- !ruby/object:Gem::Version
|
103
50
|
version: '0'
|
104
51
|
requirements: []
|
105
|
-
rubygems_version: 3.
|
106
|
-
signing_key:
|
52
|
+
rubygems_version: 3.6.2
|
107
53
|
specification_version: 4
|
108
|
-
summary: A sampling allocation profiler
|
54
|
+
summary: A sampling allocation profiler.
|
109
55
|
test_files: []
|
@@ -1,170 +0,0 @@
|
|
1
|
-
require 'minitest/autorun'
|
2
|
-
require 'allocation_sampler'
|
3
|
-
|
4
|
-
class TestAllocationSampler < Minitest::Test
|
5
|
-
def test_initialize
|
6
|
-
assert ObjectSpace::AllocationSampler.new
|
7
|
-
end
|
8
|
-
|
9
|
-
def test_init_with_params
|
10
|
-
as = ObjectSpace::AllocationSampler.new(interval: 10)
|
11
|
-
assert_equal 10, as.interval
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_init_with_location
|
15
|
-
iseq = RubyVM::InstructionSequence.new <<-eoruby
|
16
|
-
Object.new
|
17
|
-
Object.new
|
18
|
-
eoruby
|
19
|
-
as = ObjectSpace::AllocationSampler.new(interval: 1)
|
20
|
-
as.enable
|
21
|
-
iseq.eval
|
22
|
-
as.disable
|
23
|
-
|
24
|
-
assert_equal({"Object"=>{"<compiled>"=>{1=>1, 2=>1}}}, filter(as.result))
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_location_same_line
|
28
|
-
iseq = RubyVM::InstructionSequence.new <<-eoruby
|
29
|
-
10.times { Object.new }
|
30
|
-
eoruby
|
31
|
-
as = ObjectSpace::AllocationSampler.new(interval: 1)
|
32
|
-
as.enable
|
33
|
-
iseq.eval
|
34
|
-
as.disable
|
35
|
-
|
36
|
-
assert_equal({"Object"=>{"<compiled>"=>{1=>10}}}, filter(as.result))
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_location_mixed
|
40
|
-
iseq = RubyVM::InstructionSequence.new <<-eoruby
|
41
|
-
10.times { Object.new }
|
42
|
-
Object.new
|
43
|
-
eoruby
|
44
|
-
as = ObjectSpace::AllocationSampler.new(interval: 1)
|
45
|
-
as.enable
|
46
|
-
iseq.eval
|
47
|
-
as.disable
|
48
|
-
|
49
|
-
assert_equal({"Object"=>{"<compiled>"=>{1=>10, 2=>1}}}, filter(as.result))
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_location_from_method
|
53
|
-
iseq = RubyVM::InstructionSequence.new <<-eoruby
|
54
|
-
def foo
|
55
|
-
10.times { Object.new }
|
56
|
-
Object.new
|
57
|
-
end
|
58
|
-
foo
|
59
|
-
eoruby
|
60
|
-
as = ObjectSpace::AllocationSampler.new(interval: 1)
|
61
|
-
as.enable
|
62
|
-
iseq.eval
|
63
|
-
as.disable
|
64
|
-
|
65
|
-
assert_equal({"Object"=>{"<compiled>"=>{2=>10, 3=>1}}}, filter(as.result))
|
66
|
-
end
|
67
|
-
|
68
|
-
def test_location_larger_interval
|
69
|
-
iseq = RubyVM::InstructionSequence.new <<-eom
|
70
|
-
100.times { Object.new }
|
71
|
-
100.times { Object.new }
|
72
|
-
eom
|
73
|
-
as = ObjectSpace::AllocationSampler.new(interval: 10)
|
74
|
-
as.enable
|
75
|
-
iseq.eval
|
76
|
-
as.disable
|
77
|
-
|
78
|
-
assert_equal({"Object"=>{"<compiled>"=>{1=>10, 2=>10}}}, filter(as.result))
|
79
|
-
assert_equal 201, as.allocation_count
|
80
|
-
end
|
81
|
-
|
82
|
-
def test_interval_default
|
83
|
-
as = ObjectSpace::AllocationSampler.new
|
84
|
-
assert_equal 1, as.interval
|
85
|
-
end
|
86
|
-
|
87
|
-
def test_two_with_same_type
|
88
|
-
as = ObjectSpace::AllocationSampler.new
|
89
|
-
as.enable
|
90
|
-
Object.new
|
91
|
-
Object.new
|
92
|
-
as.disable
|
93
|
-
|
94
|
-
assert_equal(2, filter(as.result)[Object.name].values.flat_map(&:values).inject(:+))
|
95
|
-
end
|
96
|
-
|
97
|
-
def test_two_with_same_type_same_line
|
98
|
-
as = ObjectSpace::AllocationSampler.new
|
99
|
-
as.enable
|
100
|
-
Object.new; Object.new
|
101
|
-
Object.new; Object.new
|
102
|
-
as.disable
|
103
|
-
|
104
|
-
assert_equal 4, as.result.allocations_by_type[Object.name]
|
105
|
-
end
|
106
|
-
|
107
|
-
class X
|
108
|
-
end
|
109
|
-
|
110
|
-
def test_expands
|
111
|
-
as = ObjectSpace::AllocationSampler.new
|
112
|
-
as.enable
|
113
|
-
500.times do
|
114
|
-
Object.new
|
115
|
-
X.new
|
116
|
-
end
|
117
|
-
Object.new
|
118
|
-
as.disable
|
119
|
-
|
120
|
-
result = as.result
|
121
|
-
assert_equal 501, result.allocations_by_type[Object.name]
|
122
|
-
assert_equal 500, result.allocations_by_type[TestAllocationSampler::X.name]
|
123
|
-
end
|
124
|
-
|
125
|
-
def d
|
126
|
-
Object.new
|
127
|
-
end
|
128
|
-
def c; 5.times { d }; end
|
129
|
-
def b; 5.times { c }; end
|
130
|
-
def a; 5.times { b }; end
|
131
|
-
|
132
|
-
def test_stack_trace
|
133
|
-
as = ObjectSpace::AllocationSampler.new
|
134
|
-
buffer = StringIO.new
|
135
|
-
stack_printer = ObjectSpace::AllocationSampler::Display::Stack.new(
|
136
|
-
output: buffer
|
137
|
-
)
|
138
|
-
as.enable
|
139
|
-
a
|
140
|
-
as.disable
|
141
|
-
|
142
|
-
as.result.by_type_with_call_tree.each do |class_name, tree|
|
143
|
-
assert_equal Object.name, class_name
|
144
|
-
root = tree.find { |node| node.name.include? __method__.to_s }
|
145
|
-
stack_printer.show root
|
146
|
-
end
|
147
|
-
assert_equal <<-eoout, buffer.string
|
148
|
-
TestAllocationSampler#test_stack_trace 0 (0.0%)
|
149
|
-
`-- TestAllocationSampler#a 0 (0.0%)
|
150
|
-
`-- TestAllocationSampler#b 0 (0.0%)
|
151
|
-
`-- TestAllocationSampler#c 0 (0.0%)
|
152
|
-
`-- TestAllocationSampler#d 125 (100.0%)
|
153
|
-
eoout
|
154
|
-
end
|
155
|
-
|
156
|
-
def test_dot
|
157
|
-
as = ObjectSpace::AllocationSampler.new
|
158
|
-
as.enable
|
159
|
-
a
|
160
|
-
as.disable
|
161
|
-
|
162
|
-
File.write 'out.dot', as.result.calltree.to_dot
|
163
|
-
end
|
164
|
-
|
165
|
-
private
|
166
|
-
|
167
|
-
def filter result
|
168
|
-
result.allocations_with_top_frame
|
169
|
-
end
|
170
|
-
end
|