rbm 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -19,10 +19,12 @@ Using rbm is quite simple. Just pass in each code fragment you want to test as a
19
19
 
20
20
  rbm "sleep 1" "sleep 5"
21
21
 
22
- You can specify the number of times to loop. You can also provide a code fragment to be run before each time each code fragment is run.
22
+ You can specify the number of times to run each code fragment.
23
+ You can also provide a code fragment to be run before all code fragments or before a code fragment.
23
24
 
24
- rbm --times 100 "sleep 0.01"
25
- rbm --prerun "n = 5" "sleep n"
25
+ rbm --times 1000 "5 / 5"
26
+ rbm --times 1000 --init "n = 5" "n / 5"
27
+ rbm --times 1000 --init "n = 5" --pre "m = 5" "n / m"
26
28
 
27
29
  You may provide a name to each code fragment to be displayed on the benchmark.
28
30
 
@@ -30,16 +32,20 @@ You may provide a name to each code fragment to be displayed on the benchmark.
30
32
 
31
33
  You can see the full usage statement at any time with `rbm --help`
32
34
 
33
- Usage: rbm [options] [--name name] code [[-N name] code...]
35
+ Usage: rbm [options] [--name name] [--pre code] code [[--name name] [--pre code] code...]
34
36
 
35
37
  Ruby Options:
36
38
  -r, --require file[,file] Files to require before benchmarking
37
39
  -I, --load-path path[,path] Paths to append to $LOAD_PATH
38
40
 
39
- Benchmark Options:
40
- -n, --times N Number of times to run each code fragment
41
- -p, --pre code Code to run before each code fragment to be benchmarked
41
+ Code Fragment Options:
42
+ -n, --times n Number of times to run each code fragment
43
+ -i, --init code Code to run before every code fragment
44
+ -c, --cleanup code Code to run after each code fragment
42
45
  -N, --name name Names the following code fragment
46
+ -p, --pre code Code to run before the follow code fragment
47
+ -P, --post code Code to run after the follow code fragment
43
48
 
44
49
  General Options:
45
- -h, --help Show this message
50
+ -v, --version Print the version and exit
51
+ -h, --help Print this message and exit
data/lib/rbm.rb CHANGED
@@ -1,5 +1,6 @@
1
- require 'optparse'
2
- require 'rbm/benchmarker'
1
+ require "optparse"
2
+ require "rbm/benchmarker"
3
+ require "rbm/version"
3
4
 
4
5
  module RBM
5
6
  class << self
@@ -19,52 +20,52 @@ module RBM
19
20
  exit
20
21
  end
21
22
 
22
- begin
23
- Benchmarker.new(fragments, options).run
24
- rescue BenchmarkerSyntaxError => e
25
- puts e
26
- exit
27
- end
23
+ Benchmarker.new(fragments, options).run
28
24
  end
29
25
 
30
26
  private
31
27
  def parse_options(args)
32
- fragments, options = [], {}
33
- current_name = nil
28
+ fragments, options = [], { :requires => [], :load_paths => [] }
29
+ current_name, current_prerun, current_postrun = nil, nil, nil
34
30
 
35
31
  op = OptionParser.new do |op|
36
- op.banner = "Usage: #{op.program_name} [options] [--name name] code [[-N name] code...]"
32
+ op.banner << " [--name name] [--pre code] code [[--name name] [--pre code] code...]"
37
33
 
38
- op.separator ''
39
- op.separator 'Ruby Options:'
34
+ op.separator ""
35
+ op.separator "Ruby Options:"
40
36
 
41
- op.on('-r', '--require file[,file]', Array, 'Files to require before benchmarking') do |list|
42
- (options[:requires] ||= []).concat(list)
43
- end
37
+ op.on("-r", "--require file[,file]", Array, "Files to require before benchmarking") { |a| options[:requires].concat(a) }
38
+ op.on("-I", "--load-path path[,path]", Array, "Paths to append to $LOAD_PATH") { |a| options[:load_paths].concat(a) }
44
39
 
45
- op.on('-I', '--load-path path[,path]', Array, 'Paths to append to $LOAD_PATH') do |list|
46
- (options[:load_paths] ||= []).concat(list)
47
- end
40
+ # op.separator ""
41
+ # op.separator "Benchmark Options:"
48
42
 
49
- op.separator ''
50
- op.separator 'Benchmark Options:'
43
+ op.separator ""
44
+ op.separator "Code Fragment Options:"
51
45
 
52
- op.on('-n', '--times N', Integer, 'Number of times to run each code fragment') { |n| options[:times] = n }
53
- op.on('-p', '--pre code', String, 'Code to run before each code fragment to be benchmarked') { |p| options[:prerun] = p }
54
- op.on('-N', '--name name', String, 'Names the following code fragment') { |n| current_name = n }
46
+ op.on("-n", "--times n", Integer, "Number of times to run each code fragment") { |i| options[:times] = i }
47
+ op.on("-i", "--init code", String, "Code to run before every code fragment") { |s| options[:init] = s }
48
+ op.on("-c", "--cleanup code", String, "Code to run after each code fragment") { |s| options[:cleanup] = s }
49
+ op.on("-N", "--name name", String, "Names the following code fragment") { |s| current_name = s }
50
+ op.on("-p", "--pre code", String, "Code to run before the follow code fragment") { |s| current_prerun = s }
51
+ op.on("-P", "--post code", String, "Code to run after the follow code fragment") { |s| current_postrun = s }
55
52
 
56
- op.separator ''
57
- op.separator 'General Options:'
53
+ op.separator ""
54
+ op.separator "General Options:"
58
55
 
59
- op.on('-h', '--help', 'Show this message') do
56
+ op.on("-v", "--version", "Print the version and exit") do
57
+ puts "RBM #{RBM::VERSION}"
58
+ exit
59
+ end
60
+ op.on("-h", "--help", "Print this message and exit") do
60
61
  puts op
61
62
  exit
62
63
  end
63
64
  end
64
65
  op.order!(args) do |fragment|
65
66
  # block gets run for each non-option argument
66
- fragments << [current_name || '', fragment]
67
- current_name = nil
67
+ fragments << { :name => current_name, :prerun => current_prerun, :postrun => current_postrun, :fragment => fragment }
68
+ current_name, current_prerun, current_postrun = nil, nil, nil
68
69
  end
69
70
 
70
71
  if fragments.empty?
@@ -6,68 +6,33 @@ module RBM
6
6
  :times => 1
7
7
  }
8
8
 
9
- attr_reader :options
9
+ attr_reader :fragments, :options
10
10
 
11
11
  def initialize(fragments, options)
12
- @options = DEFAULT_OPTIONS.merge(options)
13
-
14
- compile_prerun(options[:prerun])
15
- @fragments = fragments.map { |name, fragment| [name, compile_fragment(fragment, options[:prerun], name)] }
12
+ @fragments, @options = fragments, DEFAULT_OPTIONS.merge(options)
16
13
  end
17
14
 
18
15
  def run
19
- width = @fragments.map { |name, method| name.size }.max
16
+ width = fragments.map { |fragment| (fragment[:name] || "").length }.max
20
17
  Benchmark.bm(width) do |bm|
21
- @fragments.each do |name, method|
22
- bm.report(name) do
23
- # TODO: wrap errors from fragment execution
24
- options[:times].times { send(method) }
25
- end
26
- end
27
- end
28
- end
18
+ fragments.each do |fragment|
19
+ name = fragment[:name] || ""
20
+ fragment_name = (fragment[:name] || (@unnamed_fragment ||= "fragment_0").succ!).gsub(/\s+/, "_")
29
21
 
30
- private
31
- def compile_prerun(prerun)
32
- # TODO:
33
- # another way to check prerun syntax outside of compile_fragment so we can
34
- # give meaningful syntax errors (error in prerun not in a fragment itself)
35
- wrap_syntax_errors do
36
- instance_eval <<-EVAL, "prerun", -1
37
- def bm_prerun
38
- #{prerun}
39
- end
40
- undef bm_prerun
41
- EVAL
42
- end
43
- end
22
+ object = Object.new
23
+ binding = object.send(:binding)
44
24
 
45
- def compile_fragment(fragment, prerun = nil, name = nil)
46
- name = (@fragment_name ||= "fragment_0").succ! unless name && !name.empty?
47
- fragment_name = "bm_#{name.gsub(/\s+/, '_')}".to_sym
48
- defined = instance_method(fragment_name) rescue false
49
- raise "#{fragment_name} is already defined" if defined
25
+ bm.report(name) do
26
+ # TODO: figure out how to not eval each loop but still provide a better stack trace
50
27
 
51
- wrap_syntax_errors do
52
- # TODO: provide better runtime errors and NameError errors and cleaner stack trace
53
- instance_eval <<-EVAL, name, -1
54
- def #{fragment_name}
55
- #{prerun}
56
- #{fragment}
57
- end
58
- EVAL
28
+ eval options[:init], binding, "init", 1 if options[:init]
29
+ eval fragment[:prerun], binding, "#{fragment_name}_prerun", 1 if fragment[:prerun]
30
+ options[:times].times { eval fragment[:fragment], binding, fragment_name, 1 }
31
+ eval fragment[:postrun], binding, "#{fragment_name}_postrun", 1 if fragment[:postrun]
32
+ eval options[:cleanup], binding, "cleanup", 1 if options[:cleanup]
33
+ end
59
34
  end
60
-
61
- fragment_name
62
- end
63
-
64
- def wrap_syntax_errors
65
- yield
66
- rescue SyntaxError => e
67
- raise(BenchmarkerSyntaxError.new(e.to_s))
68
35
  end
69
- end
70
-
71
- class BenchmarkerSyntaxError < SyntaxError
36
+ end
72
37
  end
73
38
  end
@@ -1,3 +1,3 @@
1
1
  module RBM
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: rbm
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.1
5
+ version: 0.0.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Samuel Kadolph
@@ -10,11 +10,11 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-03-14 00:00:00 -04:00
13
+ date: 2011-04-13 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies: []
16
16
 
17
- description: Command line tool for doing quick ruby benchmarks. Provide each code fragment to run as a separate code fragment to rbm.See rbm --help for more information.
17
+ description: Command line tool for doing quick ruby benchmarks. Provide each code fragment to run as a separate code fragment to rbm. See rbm --help for more information.
18
18
  email:
19
19
  - samuel@kadolph.com
20
20
  executables: