# # benchmark.rb # =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 ((