require 'benchmark' class BenchByteList # These match the strings used in TestByteList.java, # though the tests here are different. EMPTY = ""; VERY_SHORT = "abc" # 3 chars SHORT = "abcdefgh" # 8 chars MEDIUM = "0abcdefghi1ABCDEFGHI2123456789" # 30 chars LONG = MEDIUM * 4 # 120 chars VERY_LONG = LONG * 4 # 480 chars SHORT_ARG = "zyxw" # 4 chars MEDIUM_ARG = SHORT_ARG + "vutsrqpo" # 12 chars LONG_ARG = MEDIUM_ARG + "nmlkjihgfedcba" # 26 chars class << self def bench_string_sort(loops,str='test this string') arr = [] 5000.times do arr << str + (rand(10000)).to_s end puts "Measure string array sort time" 5.times { puts Benchmark.measure { loops.times { arr.sort } } } end def bench_hash_put(loops,str='test this string') arr = [] 500.times do arr << str + (rand(10000)).to_s end puts "Measure hash put time" 5.times { puts Benchmark.measure { loops.times { hash = {} arr.each do |key| hash[key] = :value end } } } end def bench_hash_get(loops,str='test this string') hash = {} arr = [] 500.times do key = str + (rand(10000)).to_s arr << key hash[key] = :value end puts "Measure hash get time (note: not same scale as put test)" 5.times { puts Benchmark.measure { loops.times { t = nil arr.each do |key| hash[key] hash[key] hash[key] hash[key] hash[key] hash[key] hash[key] hash[key] hash[key] hash[key] end } } } end def bench_string_eq(loops) empty1 = EMPTY empty2 = EMPTY.dup vshort1 = VERY_SHORT vshort2 = VERY_SHORT.dup short1 = SHORT short2 = SHORT.dup medium1 = MEDIUM medium2 = MEDIUM.dup long1 = LONG long2 = LONG.dup vlong1 = VERY_LONG vlong2 = VERY_LONG.dup puts "Measure string == comparison time" 5.times { puts Benchmark.measure { eq = nil (loops*500).times { empty1 == empty2 vshort1 == vshort2 short1 == short2 medium1 == medium2 long1 == long2 vlong1 == vlong2 empty1 == empty2 vshort1 == vshort2 short1 == short2 medium1 == medium2 long1 == long2 vlong1 == vlong2 } } } end def bench_string_not_eq(loops) single1 = 'A' single2 = 'B' vshort1 = VERY_SHORT + 'A' vshort2 = VERY_SHORT + 'B' short1 = SHORT + 'A' short2 = SHORT + 'B' medium1 = MEDIUM + 'A' medium2 = MEDIUM + 'B' long1 = LONG + 'A' long2 = LONG + 'B' vlong1 = VERY_LONG + 'A' vlong2 = VERY_LONG + 'B' puts "Measure string == comparison time, different last pos" 5.times { puts Benchmark.measure { eq = nil (loops*500).times { single1 == single2 vshort1 == vshort2 short1 == short2 medium1 == medium2 long1 == long2 vlong1 == vlong2 single1 == single2 vshort1 == vshort2 short1 == short2 medium1 == medium2 long1 == long2 vlong1 == vlong2 } } } end def bench_string_cmp(loops) empty1 = EMPTY empty2 = EMPTY.dup vshort1 = VERY_SHORT vshort2 = VERY_SHORT.dup short1 = SHORT short2 = SHORT.dup medium1 = MEDIUM medium2 = MEDIUM.dup long1 = LONG long2 = LONG.dup vlong1 = VERY_LONG vlong2 = VERY_LONG.dup puts "Measure string <=> comparison time" 5.times { puts Benchmark.measure { (loops*500).times { empty1 <=> empty2 vshort1 <=> vshort2 short1 <=> short2 medium1 <=> medium2 long1 <=> long2 vlong1 <=> vlong2 empty1 <=> empty2 vshort1 <=> vshort2 short1 <=> short2 medium1 <=> medium2 long1 <=> long2 vlong1 <=> vlong2 } } } end def bench_cmp_expensive_unassigned_strings!(loops) puts "Unassigned strings are expensive! (e.g, 'xxxx' <=> 'yyyy')" 5.times { puts Benchmark.measure { cmp = nil (loops*500).times { 'xxxxxxxxxa' <=> 'xxxxxxxxxb' 'xxxxxxxxxa' <=> 'xxxxxxxxxb' 'xxxxxxxxxa' <=> 'xxxxxxxxxb' 'xxxxxxxxxa' <=> 'xxxxxxxxxb' 'xxxxxxxxxa' <=> 'xxxxxxxxxb' 'xxxxxxxxxa' <=> 'xxxxxxxxxb' 'xxxxxxxxxa' <=> 'xxxxxxxxxb' 'xxxxxxxxxa' <=> 'xxxxxxxxxb' 'xxxxxxxxxa' <=> 'xxxxxxxxxb' 'xxxxxxxxxa' <=> 'xxxxxxxxxb' } } } end def bench_string_index_char(loops) arr = [] 0.upto(250) do |i| arr << ('x' * i + '.' + 'x') end puts "Measure 'string'.index(fixnum) time" 5.times { puts Benchmark.measure { idx = nil loops.times { 0.upto(250) do |i| val = arr[i] val.index(46) # 46 => '.' val.index(46) val.index(46) val.index(46) val.index(46) val.index(46) val.index(46) val.index(46) val.index(46) val.index(46) end } } } end def bench_string_index_str(loops) chars = 'abcdefghijklmnopqrstuvwxyz' search = [] 1.upto(26) do |i| search << chars[0,i] end arr = [] 0.upto(250) do |i| arr << ('x' * i + search[i%26] + 'x') end puts "Measure 'string'.index(str) time" 5.times { puts Benchmark.measure { loops.times { 0.upto(250) do |i| val = arr[i] srch = search[i%26] val.index(srch) val.index(srch) val.index(srch) val.index(srch) val.index(srch) val.index(srch) val.index(srch) val.index(srch) val.index(srch) val.index(srch) end } } } end def bench_string_rindex_char(loops) arr = [] 0.upto(250) do |i| arr << ('x' + '.' + ('x' * i)) end puts "Measure 'string'.rindex(fixnum) time" 5.times { puts Benchmark.measure { loops.times { 0.upto(250) do |i| val = arr[i] val.rindex(46) # 46 => '.' val.rindex(46) val.rindex(46) val.rindex(46) val.rindex(46) val.rindex(46) val.rindex(46) val.rindex(46) val.rindex(46) val.rindex(46) end } } } end def bench_string_rindex_str(loops) chars = 'abcdefghijklmnopqrstuvwxyz' search = [] 1.upto(26) do |i| search << chars[0,i] end arr = [] 0.upto(250) do |i| arr << ('x' + search[i%26] + ('x' * i)) end puts "Measure 'string'.rindex(str) time" 5.times { puts Benchmark.measure { loops.times { 0.upto(250) do |i| val = arr[i] srch = search[i%26] val.rindex(srch) val.rindex(srch) val.rindex(srch) val.rindex(srch) val.rindex(srch) val.rindex(srch) val.rindex(srch) val.rindex(srch) val.rindex(srch) val.rindex(srch) end } } } end def run(loops=1000) bench_string_sort(loops) bench_hash_put(loops) bench_hash_get(loops) bench_string_eq(loops) bench_string_not_eq(loops) bench_string_cmp(loops) #bench_cmp_expensive_unassigned_strings!(loops) bench_string_index_char(loops) bench_string_index_str(loops) bench_string_rindex_char(loops) bench_string_rindex_str(loops) end end #self end #ByteListBench BenchByteList.run