```なかだです。

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