diffbench 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,11 +1,10 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  gem "git"
4
+ gem "rainbow"
4
5
  group :development do
5
6
  gem "rspec", "~> 2.8.0"
6
- gem "rdoc", "~> 3.12"
7
- gem "cucumber", ">= 0"
8
7
  gem "bundler", "~> 1.1.0"
9
8
  gem "jeweler", "~> 1.8.3"
10
- gem "rcov", ">= 0"
9
+ gem "debugger"
11
10
  end
data/README.md CHANGED
@@ -1,15 +1,20 @@
1
1
  # Diffbench
2
2
 
3
- Diffbench is tool the I end up during many many performance patches to:
3
+ Diffbench is a tool I end up during many performance patches to:
4
4
 
5
5
  * Rails
6
6
  * ActiveRecord - [#5467](https://github.com/rails/rails/pull/5467)
7
7
  * ActiveModel - [#5431](https://github.com/rails/rails/pull/5431)
8
8
  * ActiveSupport - [#4493](https://github.com/rails/rails/pull/4493)
9
+ * ActionPack - [#5957](https://github.com/rails/rails/pull/5957)
9
10
  * Mail - [#396](https://github.com/mikel/mail/pull/369), [#366](https://github.com/mikel/mail/pull/366)
10
11
 
11
12
  It runs a same benchmark code before and after applying a patch.
12
13
 
14
+ ## Requirements
15
+
16
+ * Git
17
+
13
18
  ## Installation
14
19
 
15
20
  ``` sh
@@ -76,3 +81,10 @@ Before patch: 0.000000 0.000000 0.000000 ( 0.002354)
76
81
  ```
77
82
 
78
83
 
84
+ ## Self-Promotion
85
+
86
+ Like diffbench?
87
+
88
+ Follow the [repository on GitHub](https://github.com/bogdan/diffbench).
89
+
90
+ Read [author blog](http://gusiev.com).
data/Rakefile CHANGED
@@ -37,17 +37,6 @@ RSpec::Core::RakeTask.new(:rcov) do |spec|
37
37
  spec.rcov = true
38
38
  end
39
39
 
40
- require 'cucumber/rake/task'
41
- Cucumber::Rake::Task.new(:features)
42
40
 
43
41
  task :default => :spec
44
42
 
45
- require 'rdoc/task'
46
- Rake::RDocTask.new do |rdoc|
47
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
-
49
- rdoc.rdoc_dir = 'rdoc'
50
- rdoc.title = "diffbench #{version}"
51
- rdoc.rdoc_files.include('README*')
52
- rdoc.rdoc_files.include('lib/**/*.rb')
53
- end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.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.1.1"
8
+ s.version = "0.2.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-03-27"
12
+ s.date = "2012-05-22"
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"]
@@ -21,7 +21,6 @@ Gem::Specification.new do |s|
21
21
  ".document",
22
22
  ".rspec",
23
23
  "Gemfile",
24
- "Gemfile.lock",
25
24
  "LICENSE.txt",
26
25
  "README.md",
27
26
  "Rakefile",
@@ -33,6 +32,8 @@ Gem::Specification.new do |s|
33
32
  "features/support/env.rb",
34
33
  "lib/diff_bench.rb",
35
34
  "lib/diffbench.rb",
35
+ "lib/diffbench/bm.rb",
36
+ "lib/diffbench/encoder.rb",
36
37
  "spec/bench.rb",
37
38
  "spec/code.rb",
38
39
  "spec/diffbench_spec.rb",
@@ -41,7 +42,7 @@ Gem::Specification.new do |s|
41
42
  s.homepage = "http://github.com/bogdan/diffbench"
42
43
  s.licenses = ["MIT"]
43
44
  s.require_paths = ["lib"]
44
- s.rubygems_version = "1.8.10"
45
+ s.rubygems_version = "1.8.11"
45
46
  s.summary = "Benchmark your before and after some changes made"
46
47
 
47
48
  if s.respond_to? :specification_version then
@@ -49,29 +50,26 @@ Gem::Specification.new do |s|
49
50
 
50
51
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
51
52
  s.add_runtime_dependency(%q<git>, [">= 0"])
53
+ s.add_runtime_dependency(%q<rainbow>, [">= 0"])
52
54
  s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
53
- s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
54
- s.add_development_dependency(%q<cucumber>, [">= 0"])
55
55
  s.add_development_dependency(%q<bundler>, ["~> 1.1.0"])
56
56
  s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
57
- s.add_development_dependency(%q<rcov>, [">= 0"])
57
+ s.add_development_dependency(%q<debugger>, [">= 0"])
58
58
  else
59
59
  s.add_dependency(%q<git>, [">= 0"])
60
+ s.add_dependency(%q<rainbow>, [">= 0"])
60
61
  s.add_dependency(%q<rspec>, ["~> 2.8.0"])
61
- s.add_dependency(%q<rdoc>, ["~> 3.12"])
62
- s.add_dependency(%q<cucumber>, [">= 0"])
63
62
  s.add_dependency(%q<bundler>, ["~> 1.1.0"])
64
63
  s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
65
- s.add_dependency(%q<rcov>, [">= 0"])
64
+ s.add_dependency(%q<debugger>, [">= 0"])
66
65
  end
67
66
  else
68
67
  s.add_dependency(%q<git>, [">= 0"])
68
+ s.add_dependency(%q<rainbow>, [">= 0"])
69
69
  s.add_dependency(%q<rspec>, ["~> 2.8.0"])
70
- s.add_dependency(%q<rdoc>, ["~> 3.12"])
71
- s.add_dependency(%q<cucumber>, [">= 0"])
72
70
  s.add_dependency(%q<bundler>, ["~> 1.1.0"])
73
71
  s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
74
- s.add_dependency(%q<rcov>, [">= 0"])
72
+ s.add_dependency(%q<debugger>, [">= 0"])
75
73
  end
76
74
  end
77
75
 
@@ -0,0 +1,20 @@
1
+ class DiffBench
2
+ class Bm
3
+ def initialize(&block)
4
+ @measures = {}
5
+ if block.arity == -1 || block.arity > 0
6
+ block.call(self)
7
+ else
8
+ instance_eval(&block)
9
+ end
10
+
11
+ print Encoder.encode(@measures)
12
+ end
13
+
14
+ def report(label)
15
+ @measures[label] = Benchmark.measure do
16
+ yield
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ class DiffBench
2
+ class Encoder
3
+ class << self
4
+ def encode(object)
5
+ "diffbench:#{Base64.encode64(object.to_yaml).gsub!("\n", "")}"
6
+ end
7
+
8
+ def decode(string)
9
+ YAML.load(Base64.decode64(string.split(":").last))
10
+ end
11
+ end
12
+ end
13
+ end
data/lib/diffbench.rb CHANGED
@@ -2,10 +2,15 @@ require "yaml"
2
2
  require "benchmark"
3
3
  require "git"
4
4
  require "base64"
5
+ require "rainbow"
6
+ require "diffbench/encoder"
7
+ require "diffbench/bm"
5
8
 
6
9
  class DiffBench
7
10
 
8
11
  class Runner
12
+ COLORS = {red: 31, green: 32}
13
+
9
14
  def initialize(file, *args)
10
15
  @file = file
11
16
  unless @file
@@ -14,39 +19,69 @@ class DiffBench
14
19
  end
15
20
 
16
21
  def run
17
- puts "Running benchmark with current working tree"
22
+ output "Running benchmark with current working tree"
18
23
  first_run = run_file
19
24
  if tree_dirty?
20
- puts "Stashing changes"
25
+ output "Stashing changes"
21
26
  git_run "stash"
22
- puts "Running benchmark with clean working tree"
27
+ output "Running benchmark with clean working tree"
23
28
  begin
24
29
  second_run = run_file
25
30
  ensure
26
- puts "Applying stashed changes back"
31
+ output "Applying stashed changes back"
27
32
  git_run "stash pop"
28
33
  end
29
34
  elsif branch = current_head
30
- puts "Checkout HEAD^"
35
+ output "Checkout HEAD^"
31
36
  git_run "checkout 'HEAD^'"
32
- puts "Running benchmark with HEAD^"
37
+ output "Running benchmark with HEAD^"
33
38
  begin
34
39
  second_run = run_file
35
40
  ensure
36
- puts "Checkout to previous HEAD again"
41
+ output "Checkout to previous HEAD again"
37
42
  git_run "checkout #{branch}"
38
43
  end
39
44
  else
40
45
  raise Error, "No current branch."
41
46
  end
42
- puts ""
47
+ output ""
43
48
  caption = "Before patch: ".gsub(/./, " ") + Benchmark::Tms::CAPTION
44
- puts caption
49
+ output caption
45
50
  first_run.keys.each do |test|
46
- puts ("-"* (caption.size - test.size)) + test
47
- puts "After patch: #{first_run[test].format}"
48
- puts "Before patch: #{second_run[test].format}"
49
- puts ""
51
+ output ("-"* (caption.size - test.size)) + test
52
+ before_patch = second_run[test]
53
+ after_patch = first_run[test]
54
+ improvement = improvement_percentage(before_patch, after_patch)
55
+ color_string = result_color(improvement)
56
+ output "After patch: #{after_patch.format}"
57
+ output "Before patch: #{before_patch.format}"
58
+ if color_string
59
+ output self.class.color("Improvement: #{improvement}%", color_string).strip
60
+ end
61
+ output ""
62
+ end
63
+ end
64
+
65
+ def improvement_percentage(before_patch, after_patch)
66
+ (((before_patch.real - after_patch.real).to_f / before_patch.real) * 100).round
67
+ end
68
+
69
+ def self.color(text, color_string)
70
+ code = COLORS[color_string]
71
+ self.color_enabled? ? "\e[#{code}m#{text}\e[0m" : text
72
+ end
73
+
74
+ def self.color_enabled?
75
+ true
76
+ end
77
+
78
+ protected
79
+
80
+ def result_color(improvement)
81
+ if (-5..5).include?(improvement)
82
+ nil
83
+ else
84
+ improvement > 0 ? :green : :red
50
85
  end
51
86
  end
52
87
 
@@ -66,7 +101,7 @@ class DiffBench
66
101
  if line.start_with?("diffbench:")
67
102
  true
68
103
  else
69
- puts line
104
+ output line
70
105
  end
71
106
  end
72
107
  if $?.to_i > 0
@@ -105,6 +140,10 @@ class DiffBench
105
140
  status = git.status
106
141
  status.deleted.any? || status.changed.any?
107
142
  end
143
+
144
+ def output(string)
145
+ puts string
146
+ end
108
147
  end
109
148
 
110
149
  class << self
@@ -118,37 +157,6 @@ class DiffBench
118
157
 
119
158
  end
120
159
 
121
- class Bm
122
- def initialize(&block)
123
- @measures = {}
124
- if block.arity == -1 || block.arity > 0
125
- block.call(self)
126
- else
127
- instance_eval(&block)
128
- end
129
-
130
- print Encoder.encode(@measures)
131
- end
132
-
133
-
134
-
135
- def report(label)
136
- @measures[label] = Benchmark.measure do
137
- yield
138
- end
139
- end
140
- end
141
-
142
- class Encoder
143
- class << self
144
- def encode(object)
145
- "diffbench:#{Base64.encode64(object.to_yaml).gsub!("\n", "")}"
146
- end
147
160
 
148
- def decode(string)
149
- YAML.load(Base64.decode64(string.split(":").last))
150
- end
151
- end
152
- end
153
161
  class Error < StandardError; end
154
162
  end
@@ -2,6 +2,11 @@ require 'spec_helper'
2
2
  require "fileutils"
3
3
 
4
4
  describe DiffBench do
5
+
6
+ def to_regexp(output)
7
+ Regexp.compile(Regexp.escape(output).gsub("NUM", "[0-9]+"))
8
+ end
9
+
5
10
  let(:repo) do
6
11
  "#{File.dirname(__FILE__)}/repo"
7
12
  end
@@ -26,7 +31,28 @@ describe DiffBench do
26
31
  end
27
32
 
28
33
  it "should run benchmark with dirty tree and clean tree" do
29
- puts `cd #{repo}; ./../../bin/diffbench bench.rb`
34
+ output = `cd #{repo}; ./../../bin/diffbench bench.rb`
35
+ output.should =~ to_regexp(<<-OUT)
36
+ Running benchmark with current working tree
37
+ --> Sleeping
38
+ --> Sleeping
39
+ Stashing changes
40
+ Running benchmark with clean working tree
41
+ --> Sleeping
42
+ --> Sleeping
43
+ Applying stashed changes back
44
+
45
+ user system total real
46
+ --------------------------------------------------Sleeper 1
47
+ After patch: 0.000000 0.000000 0.000000 ( 0.100NUM)
48
+ Before patch: 0.000000 0.000000 0.000000 ( 0.200NUM)
49
+ #{DiffBench::Runner.color("Improvement: 50%", :green)}
50
+
51
+ --------------------------------------------------Sleeper 2
52
+ After patch: 0.000000 0.000000 0.000000 ( 0.100NUM)
53
+ Before patch: 0.000000 0.000000 0.000000 ( 0.200NUM)
54
+ #{DiffBench::Runner.color("Improvement: 50%", :green)}
55
+ OUT
30
56
  end
31
57
 
32
58
  describe "when changes got commit" do
@@ -37,7 +63,28 @@ describe DiffBench do
37
63
  end
38
64
 
39
65
  it "should run benchmark with HEAD and HEAD^" do
40
- puts `cd #{repo}; ./../../bin/diffbench bench.rb`
66
+ output = `cd #{repo}; ./../../bin/diffbench bench.rb`
67
+ output.should =~ to_regexp(<<-OUT)
68
+ Running benchmark with current working tree
69
+ --> Sleeping
70
+ --> Sleeping
71
+ Checkout HEAD^
72
+ Running benchmark with HEAD^
73
+ --> Sleeping
74
+ --> Sleeping
75
+ Checkout to previous HEAD again
76
+
77
+ user system total real
78
+ --------------------------------------------------Sleeper 1
79
+ After patch: 0.000000 0.000000 0.000000 ( 0.100NUM)
80
+ Before patch: 0.000000 0.000000 0.000000 ( 0.200NUM)
81
+ #{DiffBench::Runner.color("Improvement: 50%", :green)}
82
+
83
+ --------------------------------------------------Sleeper 2
84
+ After patch: 0.000000 0.000000 0.000000 ( 0.100NUM)
85
+ Before patch: 0.000000 0.000000 0.000000 ( 0.200NUM)
86
+ #{DiffBench::Runner.color("Improvement: 50%", :green)}
87
+ OUT
41
88
  end
42
89
  end
43
90
  end
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.1.1
4
+ version: 0.2.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-03-27 00:00:00.000000000 Z
12
+ date: 2012-05-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: git
16
- requirement: &8469000 !ruby/object:Gem::Requirement
16
+ requirement: &16634260 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,43 +21,32 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *8469000
24
+ version_requirements: *16634260
25
25
  - !ruby/object:Gem::Dependency
26
- name: rspec
27
- requirement: &8467980 !ruby/object:Gem::Requirement
26
+ name: rainbow
27
+ requirement: &16633400 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
- - - ~>
30
+ - - ! '>='
31
31
  - !ruby/object:Gem::Version
32
- version: 2.8.0
33
- type: :development
32
+ version: '0'
33
+ type: :runtime
34
34
  prerelease: false
35
- version_requirements: *8467980
35
+ version_requirements: *16633400
36
36
  - !ruby/object:Gem::Dependency
37
- name: rdoc
38
- requirement: &8466960 !ruby/object:Gem::Requirement
37
+ name: rspec
38
+ requirement: &16632500 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
42
42
  - !ruby/object:Gem::Version
43
- version: '3.12'
44
- type: :development
45
- prerelease: false
46
- version_requirements: *8466960
47
- - !ruby/object:Gem::Dependency
48
- name: cucumber
49
- requirement: &8466160 !ruby/object:Gem::Requirement
50
- none: false
51
- requirements:
52
- - - ! '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
43
+ version: 2.8.0
55
44
  type: :development
56
45
  prerelease: false
57
- version_requirements: *8466160
46
+ version_requirements: *16632500
58
47
  - !ruby/object:Gem::Dependency
59
48
  name: bundler
60
- requirement: &8465060 !ruby/object:Gem::Requirement
49
+ requirement: &16631500 !ruby/object:Gem::Requirement
61
50
  none: false
62
51
  requirements:
63
52
  - - ~>
@@ -65,10 +54,10 @@ dependencies:
65
54
  version: 1.1.0
66
55
  type: :development
67
56
  prerelease: false
68
- version_requirements: *8465060
57
+ version_requirements: *16631500
69
58
  - !ruby/object:Gem::Dependency
70
59
  name: jeweler
71
- requirement: &8480380 !ruby/object:Gem::Requirement
60
+ requirement: &16649140 !ruby/object:Gem::Requirement
72
61
  none: false
73
62
  requirements:
74
63
  - - ~>
@@ -76,10 +65,10 @@ dependencies:
76
65
  version: 1.8.3
77
66
  type: :development
78
67
  prerelease: false
79
- version_requirements: *8480380
68
+ version_requirements: *16649140
80
69
  - !ruby/object:Gem::Dependency
81
- name: rcov
82
- requirement: &8479640 !ruby/object:Gem::Requirement
70
+ name: debugger
71
+ requirement: &16647760 !ruby/object:Gem::Requirement
83
72
  none: false
84
73
  requirements:
85
74
  - - ! '>='
@@ -87,7 +76,7 @@ dependencies:
87
76
  version: '0'
88
77
  type: :development
89
78
  prerelease: false
90
- version_requirements: *8479640
79
+ version_requirements: *16647760
91
80
  description: Diffbench is gem designed to benchmark the performance patches. It can
92
81
  run specified benchmark file before and after some changes made and show performance
93
82
  comparation result
@@ -102,7 +91,6 @@ files:
102
91
  - .document
103
92
  - .rspec
104
93
  - Gemfile
105
- - Gemfile.lock
106
94
  - LICENSE.txt
107
95
  - README.md
108
96
  - Rakefile
@@ -114,6 +102,8 @@ files:
114
102
  - features/support/env.rb
115
103
  - lib/diff_bench.rb
116
104
  - lib/diffbench.rb
105
+ - lib/diffbench/bm.rb
106
+ - lib/diffbench/encoder.rb
117
107
  - spec/bench.rb
118
108
  - spec/code.rb
119
109
  - spec/diffbench_spec.rb
@@ -133,7 +123,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
133
123
  version: '0'
134
124
  segments:
135
125
  - 0
136
- hash: 1579437980307483478
126
+ hash: -784782752232548335
137
127
  required_rubygems_version: !ruby/object:Gem::Requirement
138
128
  none: false
139
129
  requirements:
@@ -142,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
132
  version: '0'
143
133
  requirements: []
144
134
  rubyforge_project:
145
- rubygems_version: 1.8.10
135
+ rubygems_version: 1.8.11
146
136
  signing_key:
147
137
  specification_version: 3
148
138
  summary: Benchmark your before and after some changes made
data/Gemfile.lock DELETED
@@ -1,45 +0,0 @@
1
- GEM
2
- remote: http://rubygems.org/
3
- specs:
4
- builder (3.0.0)
5
- cucumber (1.1.9)
6
- builder (>= 2.1.2)
7
- diff-lcs (>= 1.1.2)
8
- gherkin (~> 2.9.0)
9
- json (>= 1.4.6)
10
- term-ansicolor (>= 1.0.6)
11
- diff-lcs (1.1.3)
12
- gherkin (2.9.0)
13
- json (>= 1.4.6)
14
- git (1.2.5)
15
- jeweler (1.8.3)
16
- bundler (~> 1.0)
17
- git (>= 1.2.5)
18
- rake
19
- rdoc
20
- json (1.6.5)
21
- rake (0.9.2.2)
22
- rcov (0.9.9)
23
- rdoc (3.12)
24
- json (~> 1.4)
25
- rspec (2.8.0)
26
- rspec-core (~> 2.8.0)
27
- rspec-expectations (~> 2.8.0)
28
- rspec-mocks (~> 2.8.0)
29
- rspec-core (2.8.0)
30
- rspec-expectations (2.8.0)
31
- diff-lcs (~> 1.1.2)
32
- rspec-mocks (2.8.0)
33
- term-ansicolor (1.0.7)
34
-
35
- PLATFORMS
36
- ruby
37
-
38
- DEPENDENCIES
39
- bundler (~> 1.1.0)
40
- cucumber
41
- git
42
- jeweler (~> 1.8.3)
43
- rcov
44
- rdoc (~> 3.12)
45
- rspec (~> 2.8.0)