diffbench 0.1.1 → 0.2.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
@@ -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)