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.
@@ -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
@@ -0,0 +1,5 @@
1
+ module Benchmark
2
+ module Memory
3
+ VERSION = "0.1.0".freeze
4
+ end
5
+ 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: