benchmark-memory 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: