Hi, Brian,

> From: "Brian Candler" <B.Candler / pobox.com>
> Sent: Friday, March 07, 2003 9:22 AM

> In fact, using dRuby instead of SOAP, it takes only 0.3 seconds to do ten
> complete RPC exchanges, including the actual server work of a DBI query and
> building the return object tree each time!
> 
> I can hardly ignore a performance factor of 250 times...

250 times!  Definitely rpc via soap is slower than drb,
but 250 times is too much.  I think there should be another
bottleneck, TCP socket creation, loading WSDL everytime for example.

I tried to benchmark it myself.  Testsuit is attached at the bottom
of this mail.  Calling a method 500 times.

$ ruby18 tst.rb
# stub, user, system, total, real
direct_stub      0.200000   0.000000   0.200000 (  0.202000)
drb_stub         0.721000   0.771000   1.492000 (  4.855000)
soap_stub       18.116000   4.627000  22.743000 ( 61.047000)

In this testsuit, soap_stub is 13 times as slow as drb,
300 times as direct method call.

Hmm.  DRb may run faster I think...  seki-san?

  ruby: ruby 1.8.0 (2003-03-05) [i386-cygwin]
  drb: 2.0.2
  webrick: 1.3.0
  soap4r: 1.4.8.1
    http-access2: j

Regards,
// NaHi


== tst.rb

require 'client'
require 'soap/driver'
require 'drb/drb'

def direct_stub
  require 'servant'
  Servant.new
end

def soap_stub
  drv = SOAP::Driver.new(nil, nil, 'http://tempuri.org/node',
    'http://localhost:2000/soapsrv')
  drv.addMethod('traverse_node', 'node')
  drv
end

def drb_stub
  DRb.start_service
  DRbObject.new(nil, 'druby://localhost:2001')
end

Client.new(direct_stub).run(    'direct_stub    ', 500)
Client.new(drb_stub).run(       'drb_stub       ', 500)
Client.new(soap_stub).run(      'soap_stub      ', 500)


== client

require 'node'
require 'benchmark'

class Client
  def initialize(srv)
    @srv = srv
  end

  def run(title, n)
    node = setup_node
    Benchmark.benchmark do |bm|
      count = 0
      bm.report(title) do
        n.times do
          count = @srv.traverse_node(node)
        end
      end
    end
  end

  def setup_node
    n9 = Node.new
    n81 = Node.new(n9)
    n82 = Node.new(n9)
    n7 = Node.new(n81, n82)
    n61 = Node.new(n7)
    n62 = Node.new(n7)
    n5 = Node.new(n61, n62)
    n41 = Node.new(n5)
    n42 = Node.new(n5)
    n3 = Node.new(n41, n42)
    n21 = Node.new(n3)
    n22 = Node.new(n3)
    n1 = Node.new(n21, n22)
    n1
  end
end


== node.rb

class Node
  attr_reader :first, :second
  def initialize( *initNext )
    @first = initNext[0]
    @second = initNext[1]
  end
end


== servant.rb

require 'node'

class Servant
  def traverse_node(node)
    Thread.current[:count] = 0
    do_traverse_node(node)
    Thread.current[:count]
  end

  def do_traverse_node(node)
    if node
      Thread.current[:count] += 1
      do_traverse_node(node.first)
      do_traverse_node(node.second)
    end
  end
end


== drb_server.rb

require 'drb/drb'
require 'servant'

druby = 'druby://localhost:2001'
DRb.start_service(druby, Servant.new)
DRb.thread.join


== soap_server.rb

require 'soaplet'
require 'servant'
require 'webrick'

soapsrv = WEBrick::SOAPlet.new
soapsrv.addServant('http://tempuri.org/node', Servant.new)

svr = WEBrick::HTTPServer.new(:Port => 2000, :AccessLog => {})
svr.mount('/soapsrv', soapsrv)
svr.start