Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

file 107 lines (96 sloc) 2.462 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107

class Perf

  def initialize()
    @items = []
  end

  def add(title, op, &blk)
    @items << Item.new(title, op, &blk)
  end

  def before(title, &blk)
    @items.each do |i|
      if title == i.title
        i.set_before(&blk)
        break
      end
    end
  end
  
  def run(iter)
    base = Item.new(nil, nil) { }
    base.run(iter, 0.0)
    @items.each do |i|
      i.run(iter, base.duration)
      if i.error.nil?
        puts "#{i.title}.#{i.op} #{iter} times in %0.3f seconds or %0.3f #{i.op}/sec." % [i.duration, iter / i.duration]
      else
        puts "***** #{i.title}.#{i.op} failed! #{i.error}"
      end
    end
    summary()
  end

  def summary()
    fastest = nil
    slowest = nil
    width = 6
    @items.each do |i|
      next if i.duration.nil?
      width = i.title.size if width < i.title.size
    end
    iva = @items.clone
    iva.delete_if { |i| i.duration.nil? }
    iva = iva.sort_by { |i| i.duration }
    puts
    puts "Summary:"
    puts "%*s time (secs) rate (ops/sec)" % [width, 'System']
    puts "#{'-' * width} ----------- --------------"
    iva.each do |i|
      if i.duration.nil?
      else
        puts "%*s %11.3f %14.3f" % [width, i.title, i.duration, i.rate ]
      end
    end
    puts
    puts "Comparison Matrix\n(performance factor, 2.0 means row is twice as fast as column)"
    puts ([' ' * width] + iva.map { |i| "%*s" % [width, i.title] }).join(' ')
    puts (['-' * width] + iva.map { |i| '-' * width }).join(' ')
    iva.each do |i|
      line = ["%*s" % [width, i.title]]
      iva.each do |o|
        line << "%*.2f" % [width, o.duration / i.duration]
      end
      puts line.join(' ')
    end
    puts
  end

  class Item
    attr_accessor :title
    attr_accessor :op
    attr_accessor :blk
    attr_accessor :duration
    attr_accessor :rate
    attr_accessor :error

    def initialize(title, op, &blk)
      @title = title
      @blk = blk
      @op = op
      @duration = nil
      @rate = nil
      @error = nil
      @before = nil
    end

    def set_before(&blk)
      @before = blk
    end

    def run(iter, base)
      begin
        GC.start
        @before.call unless @before.nil?
        start = Time.now
        iter.times { @blk.call }
        @duration = Time.now - start - base
        @duration = 0.0 if @duration < 0.0
        @rate = iter / @duration
      rescue Exception => e
        @error = "#{e.class}: #{e.message}"
      end
    end

  end # Item
end # Perf
Something went wrong with that request. Please try again.