ふと Fiber をさわってみたくなって、前に別のところで試したリングベンチマークというのをやっていることにしました。
リングベンチマークというのはどういうのかというと、 N 個のノード(プロセス)を用意して、1番のノードは2番に、2番のノードは3番に……というようにメッセージを送信する。で、 N 番のノードはまた1番に戻る。で、 M 回ほどメッセージの送信を終えたらおもむろに終了する。これのパフォーマンスを調べなさいっていう話。
まあ、あからさまに Erlang に有利なベンチマークなんですが(笑)。
Fiber を使うとこんな感じでしょうか。
require 'benchmark'
class Node
attr_accessor :oth
def initialize(count, oth=nil)
@oth = oth
@node = Fiber.new do
count.times do |i|
# puts "sending message [#{i}]"
v = @oth.pass(:message)
end
end
end
def pass(v=nil)
@node.pass(v)
end
end
class RingNodes
def initialize(nodes, count)
@nodes = Array.new(nodes)
@nodes[nodes-1] = Node.new(count)
(nodes-1).downto(0) do |i|
@nodes[i] = Node.new(count, @nodes[i+1])
end
@nodes[nodes-1].oth = @nodes[0]
end
def start
@nodes[0].pass
end
end
def main(nodes, count)
Benchmark.bm(15) do |x|
ring = nil
x.report("initialize") { ring = RingNodes.new(nodes, count) }
x.report("passing") { ring.start }
end
end
nodes = (ARGV[0] || 10).to_i
count = (ARGV[1] || 10).to_i
main(nodes, count)
実行結果はこんな感じでした。
% /usr/local/ruby-1.9/bin/ruby19 ~/ring.rb 10 100
user system total real
initialize 0.000000 0.000000 0.000000 ( 0.000319)
passing 0.000000 0.000000 0.000000 ( 0.003591)
% /usr/local/ruby-1.9/bin/ruby19 ~/ring.rb 100 100
user system total real
initialize 0.000000 0.000000 0.000000 ( 0.002868)
passing 0.030000 0.000000 0.030000 ( 0.038393)
% /usr/local/ruby-1.9/bin/ruby19 ~/ring.rb 1000 100
user system total real
initialize 0.040000 0.020000 0.060000 ( 0.060228)
passing 0.610000 0.010000 0.620000 ( 0.639878)
% /usr/local/ruby-1.9/bin/ruby19 ~/ring.rb 5000 100
user system total real
initialize 0.970000 0.160000 1.130000 ( 1.142228)
passing 3.690000 0.060000 3.750000 ( 3.836600)
% /usr/local/ruby-1.9/bin/ruby19 ~/ring.rb 10000 100
user system total real
initialize 4.520000 0.450000 4.970000 ( 5.042758)
passing 8.600000 0.140000 8.740000 ( 8.966811)
% /usr/local/ruby-1.9/bin/ruby19 ~/ring.rb 20000 100
user system total real
initialize 33.880000 1.470000 35.350000 ( 35.640199)
passing 28.600000 0.310000 28.910000 ( 29.607706)
だんだんキツくなっていくとはいえ、1万fiberくらいは余裕みたいですね。 Fiber かっこいい(←これ言ってみたかっただけ)。