benchmark-memory 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +16 -0
- data/CONTRIBUTING.md +50 -0
- data/LICENSE.md +21 -0
- data/README.md +183 -0
- data/Rakefile +29 -0
- data/benchmark-memory.gemspec +24 -0
- data/lib/benchmark-memory.rb +2 -0
- data/lib/benchmark/memory.rb +34 -0
- data/lib/benchmark/memory/errors.rb +7 -0
- data/lib/benchmark/memory/held_results.rb +110 -0
- data/lib/benchmark/memory/held_results/entry_serializer.rb +35 -0
- data/lib/benchmark/memory/held_results/measurement_serializer.rb +37 -0
- data/lib/benchmark/memory/held_results/metric_serializer.rb +37 -0
- data/lib/benchmark/memory/held_results/serializer.rb +64 -0
- data/lib/benchmark/memory/helpers.rb +46 -0
- data/lib/benchmark/memory/job.rb +135 -0
- data/lib/benchmark/memory/job/io_output.rb +50 -0
- data/lib/benchmark/memory/job/io_output/comparison_formatter.rb +69 -0
- data/lib/benchmark/memory/job/io_output/entry_formatter.rb +39 -0
- data/lib/benchmark/memory/job/io_output/metric_formatter.rb +34 -0
- data/lib/benchmark/memory/job/null_output.rb +26 -0
- data/lib/benchmark/memory/job/task.rb +50 -0
- data/lib/benchmark/memory/measurement.rb +80 -0
- data/lib/benchmark/memory/measurement/metric.rb +41 -0
- data/lib/benchmark/memory/report.rb +45 -0
- data/lib/benchmark/memory/report/comparison.rb +25 -0
- data/lib/benchmark/memory/report/entry.rb +32 -0
- data/lib/benchmark/memory/version.rb +5 -0
- metadata +101 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
require "benchmark/memory/helpers"
|
2
|
+
require "benchmark/memory/job/io_output/metric_formatter"
|
3
|
+
|
4
|
+
module Benchmark
|
5
|
+
module Memory
|
6
|
+
class Job
|
7
|
+
class IOOutput
|
8
|
+
# Format entries for use with the IOOutput.
|
9
|
+
class EntryFormatter
|
10
|
+
include Helpers
|
11
|
+
|
12
|
+
# Instantiate a formatter to output an entry into an IO.
|
13
|
+
#
|
14
|
+
# @param entry [Entry] The entry to format.
|
15
|
+
def initialize(entry)
|
16
|
+
@entry = entry
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [Entry] The entry to format.
|
20
|
+
attr_reader :entry
|
21
|
+
|
22
|
+
# Format entry to a string to put on the output.
|
23
|
+
#
|
24
|
+
# @return [String]
|
25
|
+
def to_s
|
26
|
+
output = StringIO.new
|
27
|
+
output << rjust(entry.label)
|
28
|
+
entry.measurement.each_with_index.map do |metric, index|
|
29
|
+
output << " " * 20 unless index == 0
|
30
|
+
output << MetricFormatter.new(metric)
|
31
|
+
output << "\n"
|
32
|
+
end
|
33
|
+
output.string
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "benchmark/memory/helpers"
|
2
|
+
|
3
|
+
module Benchmark
|
4
|
+
module Memory
|
5
|
+
class Job
|
6
|
+
class IOOutput
|
7
|
+
# Format metrics for use with the IOOutput.
|
8
|
+
class MetricFormatter
|
9
|
+
include Helpers
|
10
|
+
|
11
|
+
# Instantiate a formatter to output a metric into an IO.
|
12
|
+
#
|
13
|
+
# @param metric [Measurement::Metric] The metric to format.
|
14
|
+
def initialize(metric)
|
15
|
+
@metric = metric
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [Metric] The metric to format.
|
19
|
+
attr_reader :metric
|
20
|
+
|
21
|
+
# Format metric to a string to put on the output.
|
22
|
+
#
|
23
|
+
# @return [String]
|
24
|
+
def to_s
|
25
|
+
[
|
26
|
+
format("%s %s", scale(metric.allocated), metric.type),
|
27
|
+
format("(%s retained)", scale(metric.retained)),
|
28
|
+
].join(" ")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Benchmark
|
2
|
+
module Memory
|
3
|
+
class Job
|
4
|
+
# Swallow all output from a job.
|
5
|
+
class NullOutput
|
6
|
+
# Swallow entry output.
|
7
|
+
#
|
8
|
+
# @return [void]
|
9
|
+
def put_entry(entry)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Swallow comparison output.
|
13
|
+
#
|
14
|
+
# @return [void]
|
15
|
+
def put_comparison(comparison)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Swallow header output.
|
19
|
+
#
|
20
|
+
# @return [void]
|
21
|
+
def put_header
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "memory_profiler"
|
2
|
+
require "benchmark/memory/measurement"
|
3
|
+
|
4
|
+
module Benchmark
|
5
|
+
module Memory
|
6
|
+
class Job
|
7
|
+
# Hold a labelled job for later measurement.
|
8
|
+
class Task
|
9
|
+
# Instantiate a job task for later measurement.
|
10
|
+
#
|
11
|
+
# @param label [#to_s] The label for the benchmark.
|
12
|
+
# @param action [#call] The code to be measured.
|
13
|
+
#
|
14
|
+
# @raise [ArgumentError] if the action does not respond to `#call`.
|
15
|
+
def initialize(label, action)
|
16
|
+
unless action.respond_to?(:call)
|
17
|
+
fail(
|
18
|
+
ArgumentError,
|
19
|
+
"Invalid action (#{@action.inspect} does not respond to call)"
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
@label = label
|
24
|
+
@action = action
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [#call] The code to be measured.
|
28
|
+
attr_reader :action
|
29
|
+
|
30
|
+
# @return [#to_s] The label for the benchmark.
|
31
|
+
attr_reader :label
|
32
|
+
|
33
|
+
# Call the action and report on its memory usage.
|
34
|
+
#
|
35
|
+
# @return [Measurement] the memory usage measurement of the code.
|
36
|
+
def call
|
37
|
+
result = while_measuring_memory_usage { action.call }
|
38
|
+
|
39
|
+
Measurement.from_result(result)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def while_measuring_memory_usage(&block)
|
45
|
+
MemoryProfiler.report({}, &block)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
require "benchmark/memory/measurement/metric"
|
3
|
+
|
4
|
+
module Benchmark
|
5
|
+
module Memory
|
6
|
+
# Encapsulate the combined metrics of an action.
|
7
|
+
class Measurement
|
8
|
+
include Comparable
|
9
|
+
include Enumerable
|
10
|
+
extend Forwardable
|
11
|
+
|
12
|
+
# Create a Measurement from a MemoryProfiler::Results object.
|
13
|
+
#
|
14
|
+
# @param result [MemoryProfiler::Results]
|
15
|
+
# The results of a MemoryProfiler report.
|
16
|
+
def self.from_result(result)
|
17
|
+
memory = Metric.new(
|
18
|
+
:memsize,
|
19
|
+
result.total_allocated_memsize,
|
20
|
+
result.total_retained_memsize
|
21
|
+
)
|
22
|
+
objects = Metric.new(
|
23
|
+
:objects,
|
24
|
+
result.total_allocated,
|
25
|
+
result.total_retained
|
26
|
+
)
|
27
|
+
strings = Metric.new(
|
28
|
+
:strings,
|
29
|
+
result.strings_allocated.size,
|
30
|
+
result.strings_retained.size
|
31
|
+
)
|
32
|
+
|
33
|
+
new(:memory => memory, :objects => objects, :strings => strings)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Instantiate a Measurement of memory usage.
|
37
|
+
#
|
38
|
+
# @param memory [Metric] The memory usage of an action.
|
39
|
+
# @param objects [Metric] The object allocations of an action.
|
40
|
+
# @param strings [Metric] The string allocations of an action.
|
41
|
+
def initialize(memory:, objects:, strings:)
|
42
|
+
@memory = memory
|
43
|
+
@objects = objects
|
44
|
+
@strings = strings
|
45
|
+
@metrics = [@memory, @objects, @strings]
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [Metric] The memory allocation metric.
|
49
|
+
attr_reader :memory
|
50
|
+
|
51
|
+
# @return [Array<Metric>] The metrics for the measurement.
|
52
|
+
attr_reader :metrics
|
53
|
+
|
54
|
+
# @return [Metric] The object allocation metric.
|
55
|
+
attr_reader :objects
|
56
|
+
|
57
|
+
# @return [Metric] The string allocation metric.
|
58
|
+
attr_reader :strings
|
59
|
+
|
60
|
+
# Enumerate through the metrics when enumerating a measurement.
|
61
|
+
def_delegator :metrics, :each
|
62
|
+
|
63
|
+
# Compare two measurements for sorting purposes.
|
64
|
+
#
|
65
|
+
# @param other [Measurement] The other measurement
|
66
|
+
#
|
67
|
+
# @return [Integer]
|
68
|
+
def <=>(other)
|
69
|
+
memory <=> other.memory
|
70
|
+
end
|
71
|
+
|
72
|
+
# Total amount of allocated memory for the measurement.
|
73
|
+
#
|
74
|
+
# @return [Integer]
|
75
|
+
def allocated_memory
|
76
|
+
memory.allocated
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "benchmark/memory/helpers"
|
2
|
+
|
3
|
+
module Benchmark
|
4
|
+
module Memory
|
5
|
+
class Measurement
|
6
|
+
# Describe the ratio of allocated vs. retained memory in a measurement.
|
7
|
+
class Metric
|
8
|
+
include Comparable
|
9
|
+
|
10
|
+
# Instantiate a Metric of allocated vs. retained memory.
|
11
|
+
#
|
12
|
+
# @param type [Symbol] The type of memory allocated in the metric.
|
13
|
+
# @param allocated [Integer] The amount allocated in the metric.
|
14
|
+
# @param retained [Integer] The amount retained in the metric.
|
15
|
+
def initialize(type, allocated, retained)
|
16
|
+
@type = type
|
17
|
+
@allocated = allocated
|
18
|
+
@retained = retained
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Integer] The amount allocated in the metric.
|
22
|
+
attr_reader :allocated
|
23
|
+
|
24
|
+
# @return [Integer] The amount retained in the metric.
|
25
|
+
attr_reader :retained
|
26
|
+
|
27
|
+
# @return [Symbol] The type of memory allocated in the metric.
|
28
|
+
attr_reader :type
|
29
|
+
|
30
|
+
# Sort by the total allocated.
|
31
|
+
#
|
32
|
+
# @param other [Metric] The other metric.
|
33
|
+
#
|
34
|
+
# @return [Integer]
|
35
|
+
def <=>(other)
|
36
|
+
allocated <=> other.allocated
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "benchmark/memory/report/comparison"
|
2
|
+
require "benchmark/memory/report/entry"
|
3
|
+
|
4
|
+
module Benchmark
|
5
|
+
module Memory
|
6
|
+
# Hold the results of a set of benchmarks.
|
7
|
+
class Report
|
8
|
+
# Instantiate a report to hold entries of tasks and measurements.
|
9
|
+
#
|
10
|
+
# @return [Report]
|
11
|
+
def initialize
|
12
|
+
@entries = []
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Array<Entry>] The entries in the report.
|
16
|
+
attr_reader :entries
|
17
|
+
|
18
|
+
# Add an entry to the report.
|
19
|
+
#
|
20
|
+
# @param task [Job::Task] The task to report about.
|
21
|
+
# @param measurement [Measurement] The measurements from the task.
|
22
|
+
#
|
23
|
+
# @return [Entry] the newly created entry.
|
24
|
+
def add_entry(task, measurement)
|
25
|
+
entry = Entry.new(task.label, measurement)
|
26
|
+
entries.push(entry)
|
27
|
+
entry
|
28
|
+
end
|
29
|
+
|
30
|
+
# Return true if the report is comparable.
|
31
|
+
#
|
32
|
+
# @return [Boolean]
|
33
|
+
def comparable?
|
34
|
+
comparison.possible?
|
35
|
+
end
|
36
|
+
|
37
|
+
# Compare the entries within a report.
|
38
|
+
#
|
39
|
+
# @return [Comparison]
|
40
|
+
def comparison
|
41
|
+
@comparison ||= Comparison.new(entries)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Benchmark
|
2
|
+
module Memory
|
3
|
+
class Report
|
4
|
+
# Compare entries against each other.
|
5
|
+
class Comparison
|
6
|
+
# Instantiate a new comparison.
|
7
|
+
#
|
8
|
+
# @param entries [Array<Entry>] The entries to compare.
|
9
|
+
def initialize(entries)
|
10
|
+
@entries = entries.sort_by(&:measurement)
|
11
|
+
end
|
12
|
+
|
13
|
+
# @return [Array<Entry>] The entries to compare.
|
14
|
+
attr_reader :entries
|
15
|
+
|
16
|
+
# Check if the comparison is possible
|
17
|
+
#
|
18
|
+
# @return [Boolean]
|
19
|
+
def possible?
|
20
|
+
entries.size > 1
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
|
3
|
+
module Benchmark
|
4
|
+
module Memory
|
5
|
+
class Report
|
6
|
+
# An entry in a report about a benchmark.
|
7
|
+
class Entry
|
8
|
+
# Instantiate a new entry.
|
9
|
+
#
|
10
|
+
# @param label [#to_s] The entry label.
|
11
|
+
# @param measurement [Measurement] The measurements for the entry.
|
12
|
+
def initialize(label, measurement)
|
13
|
+
@label = label
|
14
|
+
@measurement = measurement
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [#to_s] The entry label.
|
18
|
+
attr_reader :label
|
19
|
+
|
20
|
+
# @return [Measurement] The measurements for the entry.
|
21
|
+
attr_reader :measurement
|
22
|
+
|
23
|
+
# Get the total amount of memory allocated in the entry.
|
24
|
+
#
|
25
|
+
# @return [Integer]
|
26
|
+
def allocated_memory
|
27
|
+
measurement.memory.allocated
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: benchmark-memory
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Herold
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-05-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: memory_profiler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.9'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.12'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.12'
|
41
|
+
description: Benchmark-style memory profiling for Ruby 2.1+
|
42
|
+
email:
|
43
|
+
- michael.j.herold@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- CHANGELOG.md
|
49
|
+
- CONTRIBUTING.md
|
50
|
+
- LICENSE.md
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- benchmark-memory.gemspec
|
54
|
+
- lib/benchmark-memory.rb
|
55
|
+
- lib/benchmark/memory.rb
|
56
|
+
- lib/benchmark/memory/errors.rb
|
57
|
+
- lib/benchmark/memory/held_results.rb
|
58
|
+
- lib/benchmark/memory/held_results/entry_serializer.rb
|
59
|
+
- lib/benchmark/memory/held_results/measurement_serializer.rb
|
60
|
+
- lib/benchmark/memory/held_results/metric_serializer.rb
|
61
|
+
- lib/benchmark/memory/held_results/serializer.rb
|
62
|
+
- lib/benchmark/memory/helpers.rb
|
63
|
+
- lib/benchmark/memory/job.rb
|
64
|
+
- lib/benchmark/memory/job/io_output.rb
|
65
|
+
- lib/benchmark/memory/job/io_output/comparison_formatter.rb
|
66
|
+
- lib/benchmark/memory/job/io_output/entry_formatter.rb
|
67
|
+
- lib/benchmark/memory/job/io_output/metric_formatter.rb
|
68
|
+
- lib/benchmark/memory/job/null_output.rb
|
69
|
+
- lib/benchmark/memory/job/task.rb
|
70
|
+
- lib/benchmark/memory/measurement.rb
|
71
|
+
- lib/benchmark/memory/measurement/metric.rb
|
72
|
+
- lib/benchmark/memory/report.rb
|
73
|
+
- lib/benchmark/memory/report/comparison.rb
|
74
|
+
- lib/benchmark/memory/report/entry.rb
|
75
|
+
- lib/benchmark/memory/version.rb
|
76
|
+
homepage: https://github.com/michaelherold/benchmark-memory
|
77
|
+
licenses:
|
78
|
+
- MIT
|
79
|
+
metadata: {}
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
requirements: []
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 2.5.1
|
97
|
+
signing_key:
|
98
|
+
specification_version: 4
|
99
|
+
summary: Benchmark-style memory profiling for Ruby 2.1+
|
100
|
+
test_files: []
|
101
|
+
has_rdoc:
|