mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Rewrite fiber benchmark
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65836 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
990ddcfccf
commit
748c497a6d
2 changed files with 44 additions and 103 deletions
44
benchmark/bm_vm2_fiber_chain.rb
Executable file
44
benchmark/bm_vm2_fiber_chain.rb
Executable file
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require 'benchmark'
|
||||
|
||||
def make_link(previous)
|
||||
Fiber.new do
|
||||
while message = previous.resume
|
||||
Fiber.yield(message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def run_benchmark(fibers, repeats, message = :hello)
|
||||
chain = nil
|
||||
|
||||
time = Benchmark.realtime do
|
||||
chain = Fiber.new do
|
||||
while true
|
||||
Fiber.yield(message)
|
||||
end
|
||||
end
|
||||
|
||||
(fibers - 1).times do
|
||||
chain = make_link(chain)
|
||||
end
|
||||
end
|
||||
|
||||
puts "Creating #{fibers} fibers took #{time}..."
|
||||
|
||||
time = Benchmark.realtime do
|
||||
repeats.times do
|
||||
abort "invalid result" unless chain.resume == message
|
||||
end
|
||||
end
|
||||
|
||||
puts "Passing #{repeats} messages took #{time}..."
|
||||
end
|
||||
|
||||
n = (ARGV[0] || 1000).to_i
|
||||
m = (ARGV[1] || 1000).to_i
|
||||
|
||||
5.times do
|
||||
run_benchmark(n, m)
|
||||
end
|
|
@ -1,103 +0,0 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require 'fiber'
|
||||
require 'benchmark'
|
||||
|
||||
class Ring
|
||||
attr_reader :id
|
||||
attr_accessor :attach
|
||||
|
||||
def initialize(id)
|
||||
@id = id
|
||||
#puts "Creating ring ... #{id}"
|
||||
@fiber = Fiber.new do
|
||||
pass_message
|
||||
end
|
||||
end
|
||||
|
||||
def |(other)
|
||||
other.attach = self if !other.nil?
|
||||
#puts "attaching #{@id} to #{other.id}" if !other.nil?
|
||||
other
|
||||
end
|
||||
|
||||
def resume
|
||||
@fiber.resume
|
||||
end
|
||||
|
||||
def pass_message
|
||||
#puts "I'm fiber #{@id}"
|
||||
while message = message_in
|
||||
#puts "... #{@id} I received message #{message}"
|
||||
# do something with message
|
||||
message_out(message)
|
||||
end
|
||||
end
|
||||
|
||||
def message_in
|
||||
#puts "Resuming #{@attach.id}" if !@attach.nil?
|
||||
@attach.resume if !@attach.nil?
|
||||
end
|
||||
|
||||
def message_out(message)
|
||||
Fiber.yield(message)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class RingStart < Ring
|
||||
attr_accessor :message
|
||||
def initialize(n, m, message)
|
||||
@m = m
|
||||
@message = message
|
||||
super(n)
|
||||
end
|
||||
|
||||
def pass_message
|
||||
loop { message_out(@message) }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
def create_chain_r(i, chain)
|
||||
# recursive version
|
||||
return chain if i<=0
|
||||
r = chain.nil? ? Ring.new(i) : chain | Ring.new(i)
|
||||
create_chain(i-1, r)
|
||||
end
|
||||
|
||||
def create_chain(n, chain)
|
||||
# loop version
|
||||
# needed to avoid stack overflow for high n
|
||||
n.downto(0) {
|
||||
chain = chain | Ring.new(n)
|
||||
}
|
||||
chain
|
||||
end
|
||||
|
||||
def run_benchmark(n, m)
|
||||
mess = :hello
|
||||
ringu = nil
|
||||
chain = nil
|
||||
|
||||
tm = Benchmark.measure {
|
||||
ringu = RingStart.new(0, m, mess)
|
||||
chain = create_chain(n, ringu)
|
||||
}.format("%10.6r\n").gsub!(/\(|\)/, "")
|
||||
|
||||
puts "setup time for #{n} fibers: #{tm}"
|
||||
|
||||
tm = Benchmark.measure {
|
||||
m.times { ringu.message = chain.resume }
|
||||
}.format("%10.6r\n").gsub!(/\(|\)/, "")
|
||||
|
||||
puts "execution time for #{m} messages: #{tm}"
|
||||
end
|
||||
|
||||
n = (ARGV[0] || 1000).to_i
|
||||
m = (ARGV[1] || 10000).to_i
|
||||
|
||||
5.times do
|
||||
run_benchmark(n, m)
|
||||
end
|
Loading…
Reference in a new issue