benchpress 1.0.0 → 1.1.0

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