benchpress 1.0.0 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 38edc94e8271789d69bf667ddd3b7ee3f50694c4
4
- data.tar.gz: 5c5814779e8c63a1c664216033945d21c2e914ed
3
+ metadata.gz: 1216b498d6b488f9dcf0f151afcd6311cbd85b2d
4
+ data.tar.gz: e3562fd92362931090207aadbb62f4e653bbfc2a
5
5
  SHA512:
6
- metadata.gz: 166dd6357b3d57e2a803ae4c348d9482fd10e18f329da92ef025e5f14bfbd75ed0a6576903b6a053a9d8028d0b08fe0bea243bdb480379b3ce1f1081e78d90b8
7
- data.tar.gz: 55c0ea8a9f44679627c9c8636dfb89fd7cd680fd57f662fc3848688372ba45e9e8efadd39b0566a0e10291be3b300aad70f90337a629e2c447e851377fd5d4d7
6
+ metadata.gz: ba6098bad45a269fdb1820fe318fc6b9a74d1f78ebf879d304aa5ddb426137ddebc31e872f6ae6e1fef0d57c30fb37b6951502a7f5ee33b63c02dd20db2075bb
7
+ data.tar.gz: 0d4beb74448cdb36ea4a6b51830fd66cf7c8a046aa3af3ce9cd5fa7058bdf2f3d996553592489e97b68d477f32dcaadf9a45cd434790980fa2329b13747e3fec
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
+ *.png
2
+ *.json
1
3
  *.gem
2
4
  *.rbc
3
5
  .bundle
data/Gemfile CHANGED
File without changes
File without changes
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  Benchpress
2
2
  ==========
3
3
 
4
+ [![Code Climate](https://codeclimate.com/github/baweaver/Benchpress.png)](https://codeclimate.com/github/baweaver/Benchpress)
5
+
4
6
  Pit a few ruby methods against eachother, and chart it for great glory.
5
7
 
6
8
  Props to the folks at Gruff (https://github.com/topfunky/gruff) for making this simpler to do, and to the Ruby team behind Benchmark.
@@ -15,9 +17,10 @@ c = Benchpress::Chart.new(
15
17
  string: -> { 'string' },
16
18
  symbol: -> { :symbol }
17
19
  },
18
- min: 10_000, # Minimum times to run. Default: 0
20
+ min: 50_000, # Minimum times to run. Default: 0
19
21
  max: 100_000, # Maximum times to run. Default: 1_000
20
- step: 10_000, # Step rate for next benchmark. Default: 1
22
+ step: 10_000, # Step rate for next benchmark. Default: 250
23
+ cycles: 3, # How many times to repeat, so as to get an average. Default: 1
21
24
  name: 'string_vs_symbol', # File name. Default: 'Time.now.strftime '%Y-%m-%d-%H:%M:%S''
22
25
  format: 'png' # File format. Default: png
23
26
  )
@@ -31,6 +34,27 @@ c.render :line # Line chart
31
34
  c.render :bar # Bar chart
32
35
  ```
33
36
 
34
- ![](new pic url)
37
+ ![](http://i42.tinypic.com/24oc0mo.png)
38
+
39
+ ![](http://i42.tinypic.com/2uj2xio.png)
35
40
 
36
41
  Voila! Instant chart with realtime benchmarks to demonstrate complexities of methods everywhere! Supports an arbitrary number of entities.
42
+
43
+ Want something a tinge more beefy and realistic? How about parsing 9 megs of JSON?
44
+
45
+ ```ruby
46
+ c = Benchpress::Chart.new(
47
+ entities: {
48
+ oj: -> { Oj.load json },
49
+ json: -> { JSON.load json}
50
+ },
51
+ max: 10,
52
+ step: 2,
53
+ name: '9m-json-bar'
54
+ )
55
+
56
+ c.render :bar
57
+
58
+ ```
59
+
60
+ ![](http://i40.tinypic.com/v4xpwg.png)
data/RELEASE.md CHANGED
@@ -15,3 +15,7 @@ Initial release
15
15
  * Increase in rendering options
16
16
  * Can now render bar charts.
17
17
  * More efficient stepping algorithm, decreases runtime.
18
+
19
+ # v1.1.0
20
+
21
+ * Added Cycling, for more steady data
data/Rakefile CHANGED
File without changes
@@ -20,5 +20,7 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
22
  spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+
23
25
  spec.add_runtime_dependency "gruff"
24
26
  end
File without changes
@@ -1,5 +1,3 @@
1
- require 'pry'
2
-
3
1
  module Benchpress
4
2
  class Chart
5
3
 
@@ -11,26 +9,24 @@ module Benchpress
11
9
  # theme - theme of the chart
12
10
  # entities - data methods to run against
13
11
  def initialize(opts = {})
12
+ @cycles = opts[:cycles] || 1
14
13
  @format = opts[:format] || 'png'
15
14
  @max = opts[:max] || 1000
16
15
  @min = opts[:min] || 0
17
16
  @name = opts[:name] || "#{Time.now.strftime '%Y-%m-%d-%H:%M:%S'}"
18
- @step = opts[:step] || 1
17
+ @step = opts[:step] || 250
19
18
  @theme = opts[:theme] || Gruff::Themes::THIRTYSEVEN_SIGNALS
20
19
  @entities = parse_entities opts[:entities]
21
20
  end
22
21
 
23
- # Lets you parse in entities by passing a hash in.
24
- #
25
- # Benchpress::Chart.new(
26
- # entities: {
27
- # string: -> { 'string' }
28
- # symbol: -> { :symbol }
29
- # }
30
- # )
31
- def parse_entities(entities)
32
- raise 'Must have entities' unless entities
33
- @entities = entities.each_pair.reduce([]) { |ary, (name, method)| ary << Entity.new(name => method) }
22
+ # Render dispatcher. Note to refactor a tinge later.
23
+ def render(type = :line)
24
+ create_chart_data_for(
25
+ case type
26
+ when :line then Gruff::Line.new
27
+ when :bar then Gruff::Bar.new
28
+ end
29
+ ).write image_name
34
30
  end
35
31
 
36
32
  # file_name.ext
@@ -46,34 +42,31 @@ module Benchpress
46
42
  # Caveat - If the max % step != 0, it will not render to the max. This is intended behavior.
47
43
  def step_points
48
44
  raise 'Cannot have larger step than max' if @step > @max
45
+
49
46
  @step_points ||= ((@min / @step)..(@max / @step)).reduce([]) { |steps, i| steps << @step * i }
50
47
  end
51
48
 
52
- # Only grab labels for every other run, so as to space them out a bit more.
53
- def even_labels
54
- step_points.each_with_index.reduce({}) { |hash, (val, i)| i.odd? ? hash : hash.merge!({ i => val.to_s }) }
55
- end
49
+ private
56
50
 
57
51
  # Get labels for every point
58
52
  def all_labels
59
53
  step_points.each_with_index.reduce({}) { |hash, (val, index)| hash.merge!({ index => val.to_s }) }
60
54
  end
61
55
 
62
- # Render the entities data for the chart
63
- def calculate_method_data_points
64
- @entities.each { |entity| entity.render_data(step_points) }
65
- end
66
-
67
- # Render dispatcher. Note to refactor a tinge later.
68
- def render(type = :line)
69
- calculate_method_data_points
56
+ # Lets you parse in entities by passing a hash in.
57
+ #
58
+ # Benchpress::Chart.new(
59
+ # entities: {
60
+ # string: -> { 'string' }
61
+ # symbol: -> { :symbol }
62
+ # }
63
+ # )
64
+ def parse_entities(entities)
65
+ raise 'Must have entities' unless entities
70
66
 
71
- create_chart_data_for(
72
- case type
73
- when :line then Gruff::Line.new
74
- when :bar then Gruff::Bar.new
75
- end
76
- ).write image_name
67
+ @entities = entities.reduce([]) { |ary, (name, method)|
68
+ ary << Entity.new(step_points, @cycles, name => method)
69
+ }
77
70
  end
78
71
 
79
72
  def create_chart_data_for(chart)
@@ -9,19 +9,33 @@ module Benchpress
9
9
  # Benchpress::Entity.new(string: -> { 'string' })
10
10
  #
11
11
  # Warning: Direct instantiation has been deprecated, read the
12
- def initialize(opts = {})
12
+ def initialize(steps, cycles, opts = {})
13
13
  raise 'Invalid formatting! Use "name: -> { method }"' unless opts.keys.length == 1
14
+ @cycles = cycles
15
+ @steps = steps
14
16
  @name, @method = *opts.flatten
15
- @data_points = []
16
17
  end
17
18
 
18
- def render_data(step_points)
19
- @data_points.clear
20
- step_points.each { |n| @data_points << Benchmark.measure { n.times { @method.call } }.real }
19
+ def data
20
+ [@name.to_s, flatten_data(cycle_data)]
21
21
  end
22
22
 
23
- def data
24
- [@name.to_s, @data_points]
23
+ private
24
+
25
+ def cycle_data
26
+ @cycles.times.reduce([]) { |table, _| table << measure_realtime }
25
27
  end
28
+
29
+ def measure_realtime
30
+ @steps.reduce([]) { |data, n| data << Benchmark.measure { n.times { @method.call } }.real }
31
+ end
32
+
33
+ def flatten_data(table)
34
+ if table.length == 1
35
+ table.flatten
36
+ else
37
+ table.transpose.reduce([]) { |ary, data| ary << (data.reduce(:+) / data.length) }
38
+ end
39
+ end
26
40
  end
27
41
  end
File without changes
@@ -1,3 +1,3 @@
1
1
  module Benchpress
2
- VERSION = '1.0.0'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ chart = Benchpress::Chart.new(
4
+ entities: {
5
+ string: -> { 'string' },
6
+ symbol: -> { :symbol }
7
+ },
8
+ min: 50_000, # Minimum times to run. Default: 0
9
+ max: 100_000, # Maximum times to run. Default: 1_000
10
+ step: 10_000, # Step rate for next benchmark. Default: 1
11
+ name: 'string_vs_symbol', # File name. Default: 'Time.now.strftime '%Y-%m-%d-%H:%M:%S''
12
+ format: 'png' # File format. Default: png
13
+ )
14
+
15
+ step_points = [50000, 60000, 70000, 80000, 90000, 100000]
16
+
17
+ describe 'Benchpress::Chart' do
18
+ describe '#image_name' do
19
+ it 'will return a file name' do
20
+ expect(chart.image_name).to eq('string_vs_symbol.png')
21
+ end
22
+ end
23
+
24
+ describe '#step_points' do
25
+ it 'will return an array of step points' do
26
+ expect(chart.step_points).to eq(step_points)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ # No need for let or ivar if I don't intend to mutate.
5
+ step_points = [1,2,3,4]
6
+ cycled_entity = Benchpress::Entity.new(step_points, 3, string: -> {'s'})
7
+ entity = Benchpress::Entity.new(step_points, 1, string: -> {'s'})
8
+
9
+ describe 'Benchpress::Entity' do
10
+ describe '#data' do
11
+ it 'returns an array with the method name and data points' do
12
+ name, data = entity.data
13
+
14
+ expect(name).to eq('string')
15
+ expect(data.length).to eq(4)
16
+ end
17
+
18
+ it 'does the same for a cycled entity' do
19
+ name, data = cycled_entity.data
20
+
21
+ expect(name).to eq('string')
22
+ expect(data.length).to eq(4)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'benchpress'
5
+
6
+ RSpec.configure do |config|
7
+ # some (optional) config here
8
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: benchpress
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Weaver
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-08 00:00:00.000000000 Z
11
+ date: 2014-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: gruff
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -72,6 +86,9 @@ files:
72
86
  - lib/benchpress/entity.rb
73
87
  - lib/benchpress/themes.rb
74
88
  - lib/benchpress/version.rb
89
+ - spec/chart_spec.rb
90
+ - spec/entity_spec.rb
91
+ - spec/spec_helper.rb
75
92
  homepage: https://github.com/baweaver/Benchpress
76
93
  licenses:
77
94
  - MIT
@@ -92,8 +109,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
92
109
  version: '0'
93
110
  requirements: []
94
111
  rubyforge_project:
95
- rubygems_version: 2.1.10
112
+ rubygems_version: 2.2.1
96
113
  signing_key:
97
114
  specification_version: 4
98
115
  summary: Ruby Benchmark + Gruff to auto-gen charts for method profiline
99
- test_files: []
116
+ test_files:
117
+ - spec/chart_spec.rb
118
+ - spec/entity_spec.rb
119
+ - spec/spec_helper.rb