なかだです。

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るくらいがちょうどいいかも;-)" 伸悦