From 997b69cb6ac9eb97ea644276f1af886a49c1de03 Mon Sep 17 00:00:00 2001 From: matz Date: Thu, 14 Mar 2002 06:23:46 +0000 Subject: * re.c (rb_reg_match): should clear $~ if operand is nil. * re.c (rb_reg_match2): ditto. * configure: merge Jonathan Baker's large file support patch [ruby-talk:35316], with read_all patch in [ruby-talk:35470]. * eval.c (rb_f_abort): optional message argument that be printed on termination. [new] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2200 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/benchmark.rb | 651 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 651 insertions(+) create mode 100644 lib/benchmark.rb (limited to 'lib/benchmark.rb') diff --git a/lib/benchmark.rb b/lib/benchmark.rb new file mode 100644 index 0000000000..e6c63a7c14 --- /dev/null +++ b/lib/benchmark.rb @@ -0,0 +1,651 @@ +# +# benchmark.rb +# +=begin + 2001-11-26: Time.times renamed Process.times for ruby17 (gotoken#notwork.org) + 2001-01-12: made bmbm module func. bmbm return Tms array. + 2001-01-10: added bmbm, Job and INSTALL.rb (gotoken#notwork.org) + 2000-04-00: report() prints tag before eval block (gotoken#notwork.org) + 2000-02-22: report(): measure -> Benchmark::measure (nakahiro#sarion.co.jp) + 2000-01-02: bug fix, documentation (gotoken#notwork.org) + 2000-01-01: measure can take a tag as opt. (nobu.nakada#nifty.ne.jp) + 2000-01-01: first release (gotoken#notwork.org) +=end + +=begin += benchmark.rb + +== NAME +((*benchmark.rb*)) - a benchmark utility + +== SYNOPSIS + ---------- + require "benchmark" + include Benchmark + ---------- + +== DESCRIPTION + +benchmark.rb provides some utilities to measure and report the +times used and passed to execute. + +== SIMPLE EXAMPLE + +=== EXAMPLE 0 +To (()) the times to make (({"a"*1_000_000})): + + ---------- + puts measure{ "a"*1_000_000 } + ---------- + +On my machine (FreeBSD 3.2 on P5100MHz) this reported as follows: + + ---------- + 1.166667 0.050000 1.216667 ( 0.571355) + ---------- + +The above shows user time, system time, user+system, and really passed +time. The unit of time is second. + +=== EXAMPLE 1 +To do some experiments sequentially, (()) is useful: + + ---------- + n = 50000 + bm do |x| + x.report{for i in 1..n; a = "1"; end} + x.report{n.times do ; a = "1"; end} + x.report{1.upto(n) do ; a = "1"; end} + end + ---------- + +The result: + ---------- + user system total real + 1.033333 0.016667 1.016667 ( 0.492106) + 1.483333 0.000000 1.483333 ( 0.694605) + 1.516667 0.000000 1.516667 ( 0.711077) + ---------- + +=== EXAMPLE 2 +To put a label in each (()): + + ---------- + n = 50000 + bm(7) do |x| + x.report("for:") {for i in 1..n; a = "1"; end} + x.report("times:") {n.times do ; a = "1"; end} + x.report("upto:") {1.upto(n) do ; a = "1"; end} + end + ---------- + +The option (({7})) specifies the offset of each report accoding to the +longest label. + +This reports as follows: + + ---------- + user system total real + for: 1.050000 0.000000 1.050000 ( 0.503462) + times: 1.533333 0.016667 1.550000 ( 0.735473) + upto: 1.500000 0.016667 1.516667 ( 0.711239) + ---------- + +=== EXAMPLE 3 + +By the way, benchmarks might seem to depend on the order of items. It +is caused by the cost of memory allocation and the garbage collection. +To prevent this boresome, Benchmark::(()) is provided, e.g., to +compare ways for sort array of strings: + + ---------- + require "rbconfig" + include Config + def file + open("%s/lib/ruby/%s.%s/tk.rb" % + [CONFIG['prefix'],CONFIG['MAJOR'],CONFIG['MINOR']]).read + end + + n = 10 + bmbm do |x| + x.report("destructive!"){ + t = (file*n).to_a; t.each{|line| line.upcase!}; t.sort! + } + x.report("method chain"){ + t = (file*n).to_a.collect{|line| line.upcase}.sort + } + end + ---------- + +This reports: + + ---------- + Rehearsal ------------------------------------------------ + destructive! 2.664062 0.070312 2.734375 ( 2.783401) + method chain 5.257812 0.156250 5.414062 ( 5.736088) + --------------------------------------- total: 8.148438sec + + user system total real + destructive! 2.359375 0.007812 2.367188 ( 2.381015) + method chain 3.046875 0.023438 3.070312 ( 3.085816) + ---------- + +=== EXAMPLE 4 +To report statistics of sequential experiments with unique label, +(()) is available: + + ---------- + n = 50000 + benchmark(" "*7 + CAPTION, 7, FMTSTR, ">total:", ">avg:") do |x| + tf = x.report("for:") {for i in 1..n; a = "1"; end} + tt = x.report("times:"){n.times do ; a = "1"; end} + tu = x.report("upto:") {1.upto(n) do ; a = "1"; end} + [tf+tt+tu, (tf+tt+tu)/3] + end + ---------- + +The result: + + ---------- + user system total real + for: 1.016667 0.016667 1.033333 ( 0.485749) + times: 1.450000 0.016667 1.466667 ( 0.681367) + upto: 1.533333 0.000000 1.533333 ( 0.722166) + >total: 4.000000 0.033333 4.033333 ( 1.889282) + >avg: 1.333333 0.011111 1.344444 ( 0.629761) + ---------- + +== Benchmark module + +=== CONSTANT +:CAPTION + CAPTION is a caption string which is used in Benchmark::(()) and + Benchmark::Report#(()). +:FMTSTR + FMTSTR is a format string which is used in Benchmark::(()) and + Benchmark::Report#(()). See also Benchmark::Tms#(()). +:BENCHMARK_VERSION + BENCHMARK_VERSION is version string which statnds for the last modification + date (YYYY-MM-DD). + +=== INNER CLASS +* (()) +* (()) +* (()) + +=== MODULE FUNCTION +==== benchmark + ---------- + benchmark([caption [, label_width [, fmtstr]]]) do |x| ... end + benchmark([caption [, label_width [, fmtstr]]]) do array_of_Tms end + benchmark([caption [, label_width [, fmtstr [, labels...]]]]) do + ... + array_of_Tms + end + ---------- + +(({benchmark})) reports the times. In the first form the block variable x is +treated as a (()) object, which has (()) method. +In the second form, each member of array_of_Tms is reported in the +specified form if the member is a (()) object. The +last form provides combined above two forms (See (())). + +The following lists the meaning of each option. + +:caption + A string ((|caption|)) is printed once before execution of the given block. + +:label_width + An integer ((|label_width|)) is used as an offset in each report. + +:fmtstr + An string ((|fmtstr|)) is used to format each measurement. + See (()) + +:labels + The rest parameters labels is used as prefix of the format to the + value of block, that is array_of_Tms. + +==== bm + ---------- + bm([label_width [, labels ...]) do ... end + ---------- + +(({bm})) is a simpler interface of (()). +(({bm})) acts as same as follows: + + benchmark(" "*label_width + CAPTION, label_width, FMTSTR, *labels) do + ... + end + +==== bmbm + ---------- + bmbm([label_width]) do |x| + x.item("label1") { .... } + .... + end + ---------- + +(({bmbm})) is yet another (()). This utility function is +provited to prevent a kind of job order dependency, which is caused +by memory allocation and object creation. The usage is similar to +(()) but has less options and does extra three things: + + (1) ((*Rehearsal*)): runs all items in the job (()) to allocate + enough memory. + (2) ((*GC*)): before each (())ment, invokes (({GC.start})) to + prevent the influence of previous job. + (3) If given ((|label_width|)) is less than the maximal width of labels + given as ((|item|))'s argument, the latter is used. + Because (({bmbm})) is a 2-pass procedure, this is possible. + +(({bmbm})) returns an array which consists of Tms correspoding to each +(({item})). +==== measure + ---------- + measure([label]) do ... end + ---------- + +measure returns the times used and passed to execute the given block as a +Benchmark::Tms object. + +==== realtime + ---------- + realtime do ... end + ---------- + +realtime returns the times passed to execute the given block. + +== Benchmark::Report + +=== CLASS METHOD + +==== Benchmark::Report::new(width) + ---------- + Benchmark::Report::new([width [, fmtstr]]) + ---------- + +Usually, one doesn't have to use this method directly, +(({Benchmark::Report::new})) is called by (()) or (()). +((|width|)) and ((|fmtstr|)) are the offset of ((|label|)) and +format string responsively; Both of them are used in (()). + +=== METHOD + +==== report + + ---------- + report(fmt, *args) + ---------- + +This method reports label and time formated by ((|fmt|)). See +(()) of Benchmark::Tms for formatting rule. + +== Benchmark::Tms + +=== CLASS METHOD + +== Benchmark::Job + +=== CLASS METHOD + +==== Benchmark::Job::new + ---------- + Benchmark::Job::new(width) + ---------- + +Usually, one doesn't have to use this method directly, +(({Benchmark::Job::new})) is called by (()). +((|width|)) is a initial value for the offset ((|label|)) for formatting. +(()) passes its argument ((|width|)) to this constructor. + +=== METHOD + +==== item + ---------- + item(((|lable|))){ .... } + ---------- + +(({item})) registers a pair of (((|label|))) and given block as job (()). +==== width + +Maximum length of labels in (()) plus one. + +==== list + +array of array which consists of label and jop proc. + +==== report + +alias to (()). + +==== Benchmark::Tms::new + ---------- + Benchmark::Tms::new([u [, s [, cu [, cs [, re [, l]]]]]]) + ---------- + +returns new Benchmark::Tms object which has +((|u|)) as (()), +((|s|)) as (()), +((|cu|)) as (()) +((|cs|)) as (()), +((|re|)) as (()) and +((|l|)) as ((