diffbench 0.2.1 → 0.3.0

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