なかだです。 At Sat, 1 Jan 2000 10:18:23 +0900, gotoken / math.sci.hokudai.ac.jp (GOTO Kentaro) wrote: > こおいう測定は僕もよくやるので、時間の計測を簡便に行うための > ブツを書いてみました。 結構使いますよね。 > require "benchmark" > include Benchmark > > n = ARGV[0].to_i.nonzero? || 50000 > benchmark(" " + CAPTION, > "for: " + FMTSTR, > "times: " + FMTSTR, > "upto: " + FMTSTR) do > [ > measure{for i in 1..n; a = "1"; end}, # Benchmark::measure > measure{n.times do ; a = "1"; end}, > measure{1.upto(n) do ; a = "1"; end} > ] > end 改良かどうかはさておき、個人的嗜好として気になるのは 1) format をそれぞれ指定できる∴バラバラにもできる 2) ラベル(?)と計 測対象が離れ離れってとこです。 benchmark(' ' * 7 + CAPTION, 7, FMTSTR) do |b| b.measure("for:") {for i in 1..n; a = "1"; end} b.measure("times:") {n.times do ; a = "1"; end} b.measure("upto:") {1.upto(n) do ; a = "1"; end} end こんな感じの方が好みといえば好みです。 --- benchmark.rb.orig Sat Jan 1 12:49:21 2000 +++ benchmark.rb Sat Jan 1 14:27:47 2000 @@ -9,10 +9,16 @@ module Benchmark end - def benchmark(caption = "", *fmt, &blk) + def benchmark(caption = "", label_width = nil, fmtstr = nil, *fmt) + label_width ||= 0 + format ||= FMTSTR raise ArgumentError, "no block" unless iterator? - report(caption, *fmt, &blk) + print caption + results = yield(Report.new(label_width, fmtstr)) + Array === results and results.grep(Tms).each {|t| + print((fmt.shift || t.label || "").ljust(label_width), t.format(fmtstr)) + } end - def measure + def measure(label = nil) t0, r0 = Time.times, Time.now yield @@ -22,23 +28,19 @@ module Benchmark t1.cutime - t0.cutime, t1.cstime - t0.cstime, - r1.to_f - r0.to_f) + r1.to_f - r0.to_f, + label) end - def report(*args) - if iterator? - print args.shift - tms = yield - tms.each{|t| - print t.format(fmt = args.shift) - } - else - print Benchmark::CAPTION - args.each{|t| - print t - } + module_function :benchmark, :measure, :realtime + + class Report + def initialize(width = 0, fmtstr = nil) + @width, @fmtstr = width, fmtstr end - end - module_function :measure, :realtime, :report + def report(label = nil, *fmt, &blk) + print label.ljust(@width), measure(&blk).format(@fmtstr, *fmt) + end + end class Tms @@ -46,8 +48,8 @@ module Benchmark FMTSTR = "%10.6u %10.6y %10.6t %10.6r\n" - attr_reader :utime, :stime, :cutime, :cstime, :real, :total + attr_reader :utime, :stime, :cutime, :cstime, :real, :total, :label - def initialize(u = 0.0, s = 0.0, cu = 0.0, cs = 0.0, real = 0.0) - @utime, @stime, @cutime, @cstime, @real = u, s, cu, cs, real + def initialize(u = 0.0, s = 0.0, cu = 0.0, cs = 0.0, real = 0.0, l = nil) + @utime, @stime, @cutime, @cstime, @real, @label = u, s, cu, cs, real, l @total = @utime + @stime + @cutime + @cstime end @@ -72,6 +74,7 @@ module Benchmark def /(x); memberwise(:/, x) end - def format(arg0 = nil,*args) - fmtstr = arg0 ? arg0 : Benchmark::Tms::FMTSTR.dup + def format(arg0 = nil, *args) + fmtstr = (arg0 || FMTSTR).dup + fmtstr.gsub!(/(%[-+\.\d]*)n/){"#{$1}s" % label} fmtstr.gsub!(/(%[-+\.\d]*)u/){"#{$1}f" % utime} fmtstr.gsub!(/(%[-+\.\d]*)y/){"#{$1}f" % stime} @@ -121,12 +124,12 @@ if __FILE__ == $0 n = ARGV[0].to_i.nonzero? || 50000 puts %Q([#{n} times iterations of `a = "1"']) - benchmark(" " + CAPTION, - "for: " + FMTSTR, - "times: " + FMTSTR, - "upto: " + FMTSTR) do + benchmark(" " + CAPTION, 7, FMTSTR) do |x| + x.report("for:") {for i in 1..n; a = "1"; end} # Benchmark::measure + x.report("times:") {n.times do ; a = "1"; end} + x.report("upto:") {1.upto(n) do ; a = "1"; end} [ - measure{for i in 1..n; a = "1"; end}, # Benchmark::measure - measure{n.times do ; a = "1"; end}, - measure{1.upto(n) do ; a = "1"; end} + measure("for:") {for i in 1..n; a = "1"; end}, # Benchmark::measure + measure("times:") {n.times do ; a = "1"; end}, + measure("upto:") {1.upto(n) do ; a = "1"; end} ] end -- そうだ 強気に ちょっと インチキに☆彡 中田 "Bugるくらいがちょうどいいかも;-)" 伸悦