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 +3 -3
- data/README.md +5 -1
- data/VERSION +1 -1
- data/diffbench.gemspec +9 -9
- data/lib/diffbench.rb +76 -10
- data/lib/diffbench/bm.rb +1 -1
- data/spec/diffbench_spec.rb +31 -0
- metadata +43 -18
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Diffbench
|
2
2
|
|
3
|
-
Diffbench is a tool I
|
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.
|
1
|
+
0.3.0
|
data/diffbench.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "diffbench"
|
8
|
-
s.version = "0.
|
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 = "
|
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.
|
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>, ["
|
54
|
-
s.add_development_dependency(%q<bundler>, ["
|
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>, ["
|
60
|
-
s.add_dependency(%q<bundler>, ["
|
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>, ["
|
67
|
-
s.add_dependency(%q<bundler>, ["
|
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
|
data/lib/diffbench.rb
CHANGED
@@ -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
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
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
|
-
|
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
|
-
|
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:")
|
data/lib/diffbench/bm.rb
CHANGED
data/spec/diffbench_spec.rb
CHANGED
@@ -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.
|
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:
|
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:
|
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:
|
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:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
|
-
- -
|
35
|
+
- - ! '>='
|
31
36
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
37
|
+
version: '0'
|
33
38
|
type: :development
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
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:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
|
-
- -
|
51
|
+
- - ! '>='
|
42
52
|
- !ruby/object:Gem::Version
|
43
|
-
version:
|
53
|
+
version: '0'
|
44
54
|
type: :development
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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.
|
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
|