そのため、 eventmachineに TCP サーバーがあり、サーバーへの操作 (フィルターや拡張機能など) を事前に保留する方法として、rubyracer が使用されています。サーバーが大量のデータを受信していないときはすべて魅力的に機能しますが、フラッディングされているとき (必要な場合もあります) は非常に遅くなります。
そこで、Rubyracer が Ruby と比べてどれほど遅いかを確認するために小さなベンチマークを実行しました。結果を見てショックを受けました。
user system total real
V8: 0.060000 0.000000 0.060000 ( 0.059903)
Ruby: 0.000000 0.000000 0.000000 ( 0.000524)
正直なところ、遅いかどうかは気にしませんが、データの処理が完了するまでサーバー全体をロックしたくありません。を使用するEM::defer
ことは実際にはオプションではありません (試してみましたが、フラッディングの程度によっては、膨大な数のスレッドが生成される場合があります)。私はプロトコルを設計していないので、フラッディングを回避することはできず、クライアントはプロトコルをそのようにする必要があります (恐ろしいほど)。
ベンチマーク コード:
require 'v8'
require 'benchmark'
class User
def initialize
@name = "smack"
@sex = "female"
@age = rand(100)
@health = rand(100)
@level = rand(100)
@colour = rand(14)
end
attr_accessor :name, :sex, :age, :health, :level, :colour
end
# Create context and the function
context = V8::Context.new
code = "obj = {
__incybincy__: function() {
user.name + '' + '' + ''
user.sex + '' + '' + ''
user.age + '' + '' + ''
user.health + '' + '' + ''
user.level + '' + '' + ''
user.colour + '' + '' + ''
}
}"
context.eval(code)
# Insert the user into the context
user = User.new
context["user"] = user
# Benchmark
n = 100
Benchmark.bm do |x|
x.report("V8: ") do
n.times do
context['obj'].__incybincy__
end
end
x.report("Ruby: ") do
n.times do
user.name + "" + ""
user.sex + "" + ""
user.age.to_s + "" + ""
user.health.to_s + "" + ""
user.level.to_s + "" + ""
user.colour.to_s + "" + ""
end
end
end
編集
質問: therubyracer によるボトルネックを解消する方法はありますか? 他の方法で JavaScript を Ruby に実装することは許容されます。
2012年03月07日更新
[native code]
それで、コードを最適化することができました。なぜなら、ボトルネックの原因はRuby <-> JS通信であると考えたからです.Rubyはクラスのgetterメソッドとsetterメソッドを使用しているため、実行されるたびに発生しました.オブジェクトが言語間で直接渡されたとき。
user system total real
V8-optimized: 0.050000 0.000000 0.050000 ( 0.049733)
V8-normal: 0.870000 0.050000 0.920000 ( 0.885439)
Ruby: 0.010000 0.000000 0.010000 ( 0.015064)
#where n is 1000
そのため、JS 側でキャッシングすることにより、Ruby と JS 間の呼び出しの数を減らしましたが、少なくとも 1 つのオブジェクトを関数に渡す必要があるため、期待したほどには最適化されませんでした: aHash
または少なくともJSONの代わりString
に a を渡すことさえしましたが、Fixnum
これは FML だと叫びましたが、これは文字列を渡すよりも大きな改善ではありませんでした (仮にあったとしても)。
私はまだ私よりも優れた迅速な解決策を望んでいます。