
# Test the speed of dispatching:
#
# 

require "objectteam"


class A
  def calculate(n)
    n.times { r=(2+3)/5*100+12-2+12 }
  end
end

class B < A
  def calculate(n)
    super
    n.times { r=(2+3)/5*100+12-2+12 }
  end
end


class Test

  attr :loops
  attr :fast
  attr :medium
  attr :hard

  def initialize(loops, fast, medium, hard)
    @loops = loops
    @fast = fast
    @medium = medium
    @hard = hard
  end

  def measure(n)
    b=B.new
    result = Array.new
    for a in @loops
      start = Time.new
      a.times { 
        b.calculate(n)
      }
      stop = Time.new
      #result in millis
      result.push(((stop-start)*1000)/a)
    end
    return result
  end

  def evaluate(pure, intercepted)
    psum = 0
    isum = 0
    dsum = 0
    maxlen = @loops.last.to_s.length
    @loops.length.times { |num|
      p = pure[num]
      i = intercepted[num]
      psum += p
      isum += i
      dsum+= (i-p)
    }
    pmiddle = psum/@loops.length
    imiddle = isum/@loops.length
    dmiddle = dsum/@loops.length
    loss = (dmiddle+pmiddle)/pmiddle
    printf("pure=%.6f intercepted=%.6f   => Average: %.2f times slower\n", pmiddle, imiddle, loss)
    return loss
  end

  def test
    puts "Please wait, I will run some tests ..."

    puts "test normal behaviour ..."
    pure_fast = measure(@fast)
    pure_medium = measure(@medium)
    pure_hard = measure(@hard)
    puts "test intercepted behaviour ..."
    Interceptor.intercept_all_methods(B)
    icepted_fast = measure(@fast)
    icepted_medium = measure(@medium)
    icepted_hard = measure(@hard)

    puts "\n\nresult of pure method calls: ================================================"
    sum_fast = evaluate(pure_fast, icepted_fast)
    puts "\n\nresult of method calls with 'content': ======================================"
    sum_medium = evaluate(pure_medium, icepted_medium)
    puts "\n\nresult of method calls with a lot to do: ===================================="
    sum_hard = evaluate(pure_hard, icepted_hard)

    puts "\n\n============================================================================="
    average = (sum_hard+sum_medium+sum_fast)/3
    printf(" => Average: %.0f times slower\n", average)
  end

  def Test.main
    testrun = Test.new([100, 500,  1000], 0, 10, 100)
    testrun.test
  end
end

Test.main


# speedtest.rb   Juni 2002
#
# Copyright (c) 2002 by Matthias Veit <matthias_veit@yahoo.de>
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option) 
# any later version.
#  
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
# GNU General Public License for more details.
#  
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  
# 02111-1307, USA.
