diffbench 0.2.1 → 0.3.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.
data/Gemfile CHANGED
@@ -2,8 +2,8 @@ source "http://rubygems.org"
2
2
 
3
3
  gem "git"
4
4
  group :development do
5
- gem "rspec", "~> 2.8.0"
6
- gem "bundler", "~> 1.1.0"
5
+ gem "rspec"
6
+ gem "bundler"
7
7
  gem "jeweler", "~> 1.8.3"
8
- gem "debugger"
8
+ gem "debugger", :platform => "ruby_19"
9
9
  end
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Diffbench
2
2
 
3
- Diffbench is a tool I end up during many performance patches to:
3
+ Diffbench is a tool I made during many performance patches to:
4
4
 
5
5
  * Rails
6
6
  * ActiveRecord - [#5467](https://github.com/rails/rails/pull/5467)
@@ -79,6 +79,10 @@ Before patch: 0.020000 0.000000 0.020000 ( 0.024283)
79
79
  After patch: 0.010000 0.000000 0.010000 ( 0.002160)
80
80
  Before patch: 0.000000 0.000000 0.000000 ( 0.002354)
81
81
  ```
82
+ ## Is DiffBench safe for my repo?
83
+
84
+ DiffBench is using `git stash` and `git checkout "HEAD^"` commands to modify code in a repo.
85
+ This means that you are able to **recover** your code even **after ruby segfaults**.
82
86
 
83
87
 
84
88
  ## Self-Promotion
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.3.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "diffbench"
8
- s.version = "0.2.1"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Bogdan Gusiev"]
12
- s.date = "2012-05-22"
12
+ s.date = "2013-06-08"
13
13
  s.description = "Diffbench is gem designed to benchmark the performance patches. It can run specified benchmark file before and after some changes made and show performance comparation result"
14
14
  s.email = "agresso@gmail.com"
15
15
  s.executables = ["diffbench"]
@@ -42,7 +42,7 @@ Gem::Specification.new do |s|
42
42
  s.homepage = "http://github.com/bogdan/diffbench"
43
43
  s.licenses = ["MIT"]
44
44
  s.require_paths = ["lib"]
45
- s.rubygems_version = "1.8.11"
45
+ s.rubygems_version = "1.8.24"
46
46
  s.summary = "Benchmark your before and after some changes made"
47
47
 
48
48
  if s.respond_to? :specification_version then
@@ -50,21 +50,21 @@ Gem::Specification.new do |s|
50
50
 
51
51
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
52
52
  s.add_runtime_dependency(%q<git>, [">= 0"])
53
- s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
54
- s.add_development_dependency(%q<bundler>, ["~> 1.1.0"])
53
+ s.add_development_dependency(%q<rspec>, [">= 0"])
54
+ s.add_development_dependency(%q<bundler>, [">= 0"])
55
55
  s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
56
56
  s.add_development_dependency(%q<debugger>, [">= 0"])
57
57
  else
58
58
  s.add_dependency(%q<git>, [">= 0"])
59
- s.add_dependency(%q<rspec>, ["~> 2.8.0"])
60
- s.add_dependency(%q<bundler>, ["~> 1.1.0"])
59
+ s.add_dependency(%q<rspec>, [">= 0"])
60
+ s.add_dependency(%q<bundler>, [">= 0"])
61
61
  s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
62
62
  s.add_dependency(%q<debugger>, [">= 0"])
63
63
  end
64
64
  else
65
65
  s.add_dependency(%q<git>, [">= 0"])
66
- s.add_dependency(%q<rspec>, ["~> 2.8.0"])
67
- s.add_dependency(%q<bundler>, ["~> 1.1.0"])
66
+ s.add_dependency(%q<rspec>, [">= 0"])
67
+ s.add_dependency(%q<bundler>, [">= 0"])
68
68
  s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
69
69
  s.add_dependency(%q<debugger>, [">= 0"])
70
70
  end
@@ -2,22 +2,89 @@ require "yaml"
2
2
  require "benchmark"
3
3
  require "git"
4
4
  require "base64"
5
+ require "optparse"
5
6
  require "diffbench/encoder"
6
7
  require "diffbench/bm"
7
8
 
8
9
  class DiffBench
9
10
 
10
11
  class Runner
11
- COLORS = {red: 31, green: 32}
12
+ COLORS = {:red => 31, :green => 32, :yellow => 33}
13
+
14
+ def initialize(*args)
15
+ parser = OptionParser.new do |opts|
16
+ opts.banner = <<-DOC
17
+ Usage: diffbench [options] file
18
+
19
+ When working tree is dirty default is run benchmark againts dirty tree and clean tree.
20
+ When working tree is clean default is run benchmark against current head and previous commit.
21
+ DOC
22
+
23
+ opts.on("-r", '--revision [REVISIONS]', 'Specify revisions to run benchmark (comma separated). Example: master,f9a845,v3.1.4') do |value|
24
+ if tree_dirty?
25
+ raise Error, "Working tree is dirty."
26
+ end
27
+ @revisions = value.split(",")
28
+ end
29
+ opts.on("-b", '--before [COMMAND]', 'Specify command to run before each benchmark run. e.g. bundle install') do |value|
30
+ @before_command = value
31
+ end
12
32
 
13
- def initialize(file, *args)
14
- @file = file
15
- unless @file
16
- raise Error, "File not specified"
33
+ opts.on_tail('-h', '--help', 'Show this help') do
34
+ output opts
35
+ exit
36
+ end
17
37
  end
38
+ parser.parse!(args)
39
+ @file = args.first or raise Error, 'File not specified'
18
40
  end
19
41
 
20
42
  def run
43
+ if @revisions
44
+ run_revisions
45
+ else
46
+ run_current_head
47
+ end
48
+ end
49
+
50
+ def run_revisions
51
+ branch = current_head
52
+
53
+ results = begin
54
+ @revisions.inject({}) do |result, revision|
55
+ output "Checkout to #{revision}"
56
+ output "Run benchmark with #{revision}"
57
+ git_run("checkout '#{revision}'")
58
+ result[revision] = run_file
59
+ result
60
+ end
61
+ ensure
62
+ output "Checkout to #{branch}"
63
+ git_run("checkout '#{branch}'")
64
+ end
65
+ print_results(results)
66
+ end
67
+
68
+ def print_results(results)
69
+ output ""
70
+ #TODO set caption the right way
71
+ caption = "Before patch: ".gsub(/./, " ") + Benchmark::Tms::CAPTION
72
+ output caption
73
+ tests = results.values.first.keys
74
+ tests.each do |test|
75
+ output(("-" * (caption.size - test.size)) + test)
76
+ results.each do |revision, benchmark|
77
+ output "#{revision}: #{benchmark[test].format}"
78
+ end
79
+ #TODO set improvement
80
+ #improvement = improvement_percentage(before_patch, after_patch)
81
+ #color_string = result_color(improvement)
82
+ #output self.class.color("Improvement: #{improvement}%", color_string).strip
83
+ output ""
84
+ end
85
+ end
86
+
87
+ def run_current_head
21
88
  output "Running benchmark with current working tree"
22
89
  first_run = run_file
23
90
  if tree_dirty?
@@ -47,16 +114,14 @@ class DiffBench
47
114
  caption = "Before patch: ".gsub(/./, " ") + Benchmark::Tms::CAPTION
48
115
  output caption
49
116
  first_run.keys.each do |test|
50
- output ("-"* (caption.size - test.size)) + test
117
+ output(("-" * (caption.size - test.size)) + test)
51
118
  before_patch = second_run[test]
52
119
  after_patch = first_run[test]
53
120
  improvement = improvement_percentage(before_patch, after_patch)
54
121
  color_string = result_color(improvement)
55
122
  output "After patch: #{after_patch.format}"
56
123
  output "Before patch: #{before_patch.format}"
57
- if color_string
58
- output self.class.color("Improvement: #{improvement}%", color_string).strip
59
- end
124
+ output self.class.color("Improvement: #{improvement}%", color_string).strip
60
125
  output ""
61
126
  end
62
127
  end
@@ -78,7 +143,7 @@ class DiffBench
78
143
 
79
144
  def result_color(improvement)
80
145
  if (-5..5).include?(improvement)
81
- nil
146
+ :yellow
82
147
  else
83
148
  improvement > 0 ? :green : :red
84
149
  end
@@ -95,6 +160,7 @@ class DiffBench
95
160
  end
96
161
 
97
162
  def run_file
163
+ output `#{@before_command}` if @before_command
98
164
  output = `ruby -I#{File.dirname(__FILE__)} #{@file}`
99
165
  output.split("\n").select! do |line|
100
166
  if line.start_with?("diffbench:")
@@ -8,7 +8,7 @@ class DiffBench
8
8
  instance_eval(&block)
9
9
  end
10
10
 
11
- print Encoder.encode(@measures)
11
+ puts Encoder.encode(@measures)
12
12
  end
13
13
 
14
14
  def report(label)
@@ -55,6 +55,11 @@ Before patch: 0.000000 0.000000 0.000000 ( 0.200NUM)
55
55
  OUT
56
56
  end
57
57
 
58
+ it "should suppor before command option" do
59
+ output = `cd #{repo}; ./../../bin/diffbench -b "echo hello" bench.rb`
60
+ output.should include("hello")
61
+ end
62
+
58
63
  describe "when changes got commit" do
59
64
 
60
65
  before(:each) do
@@ -84,9 +89,35 @@ Before patch: 0.000000 0.000000 0.000000 ( 0.200NUM)
84
89
  After patch: 0.000000 0.000000 0.000000 ( 0.100NUM)
85
90
  Before patch: 0.000000 0.000000 0.000000 ( 0.200NUM)
86
91
  #{DiffBench::Runner.color("Improvement: 50%", :green)}
92
+ OUT
93
+ end
94
+
95
+ it "should run benchmark for specified revisions" do
96
+ revs = `cd #{repo};git log --pretty="%h"`.split("\n")
97
+ output = `cd #{repo}; ./../../bin/diffbench -r #{revs.join(",")} bench.rb`
98
+ output.should =~ to_regexp(<<-OUT)
99
+ Checkout to #{revs.first}
100
+ Run benchmark with #{revs.first}
101
+ --> Sleeping
102
+ --> Sleeping
103
+ Checkout to #{revs.last}
104
+ Run benchmark with #{revs.last}
105
+ --> Sleeping
106
+ --> Sleeping
107
+ Checkout to master
108
+
109
+ user system total real
110
+ --------------------------------------------------Sleeper 1
111
+ #{revs.first}: 0.000000 0.000000 0.000000 ( 0.100NUM)
112
+ #{revs.last }: 0.000000 0.000000 0.000000 ( 0.200NUM)
113
+
114
+ --------------------------------------------------Sleeper 2
115
+ #{revs.first}: 0.000000 0.000000 0.000000 ( 0.100NUM)
116
+ #{revs.last }: 0.000000 0.000000 0.000000 ( 0.200NUM)
87
117
  OUT
88
118
  end
89
119
  end
120
+
90
121
  end
91
122
 
92
123
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: diffbench
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-22 00:00:00.000000000 Z
12
+ date: 2013-06-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: git
16
- requirement: &11887460 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,32 +21,47 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *11887460
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: rspec
27
- requirement: &11886460 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
- - - ~>
35
+ - - ! '>='
31
36
  - !ruby/object:Gem::Version
32
- version: 2.8.0
37
+ version: '0'
33
38
  type: :development
34
39
  prerelease: false
35
- version_requirements: *11886460
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: bundler
38
- requirement: &11885500 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
- - - ~>
51
+ - - ! '>='
42
52
  - !ruby/object:Gem::Version
43
- version: 1.1.0
53
+ version: '0'
44
54
  type: :development
45
55
  prerelease: false
46
- version_requirements: *11885500
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: jeweler
49
- requirement: &11884740 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ~>
@@ -54,10 +69,15 @@ dependencies:
54
69
  version: 1.8.3
55
70
  type: :development
56
71
  prerelease: false
57
- version_requirements: *11884740
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 1.8.3
58
78
  - !ruby/object:Gem::Dependency
59
79
  name: debugger
60
- requirement: &11902380 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
61
81
  none: false
62
82
  requirements:
63
83
  - - ! '>='
@@ -65,7 +85,12 @@ dependencies:
65
85
  version: '0'
66
86
  type: :development
67
87
  prerelease: false
68
- version_requirements: *11902380
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
69
94
  description: Diffbench is gem designed to benchmark the performance patches. It can
70
95
  run specified benchmark file before and after some changes made and show performance
71
96
  comparation result
@@ -112,7 +137,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
112
137
  version: '0'
113
138
  segments:
114
139
  - 0
115
- hash: 2188438229192875359
140
+ hash: -2803528317631854912
116
141
  required_rubygems_version: !ruby/object:Gem::Requirement
117
142
  none: false
118
143
  requirements:
@@ -121,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
146
  version: '0'
122
147
  requirements: []
123
148
  rubyforge_project:
124
- rubygems_version: 1.8.11
149
+ rubygems_version: 1.8.24
125
150
  signing_key:
126
151
  specification_version: 3
127
152
  summary: Benchmark your before and after some changes made