benchmark-memory 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/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:
|