dRubyのパフォーマンス測定
経緯
プロセス間通信でdRubyを使おうと思ったが、パフォーマンスが気になったので測定してみた。
コード
ベンチマークは自作の次のスクリプトを使う。
github.com
のbenchmark_basic.rb
を使用。
ベンチマークコードの抜粋:
n = ARGV.shift || '1_000_000' n = n.to_i def method_no_args end def method_default(a=:foo) end def method_a1(a) end def method_a2(a, b) end def method_a3(a, b, c) end def method_args(*args) end def method_keywords(options={}) end def method_block yield end class RemoteObject def method_no_args end def method_default(a=:foo) end def method_a1(a) end def method_a2(a, b) end def method_a3(a, b, c) end def method_args(*args) end def method_keywords(options={}) end def method_block yield end end druby_remote_uri = 'drbunix:' + File.expand_path(File.join(File.dirname($0), "druby_remote.#{$$}")) druby_local_uri = 'drbunix:' + File.expand_path(File.join(File.dirname($0), "druby_local.#{$$}")) pid = fork{ DRb.start_service(druby_remote_uri, RemoteObject.new) DRb.thread.join } at_exit{ Process.kill('TERM', pid) } DRb.start_service(druby_local_uri) drb_remote_obj = DRbObject.new_with_uri(druby_remote_uri) # wait to start remote server begin drb_remote_obj.method_no_args rescue DRb::DRbConnError sleep(0.1) retry end Benchmark.bm(45) do |x| x.report('method_no_args') { n.times do method_no_args end } x.report('method_default') { n.times do method_default end } x.report('method_a1') { n.times do method_a1(1) end } x.report('method_a2') { n.times do method_a2(1, 2) end } x.report('method_a3') { n.times do method_a3(1, 2, 3) end } x.report('method_args') { n.times do method_args(1, 2, 3) end } x.report('method_keywords') { n.times do method_keywords(foo: 1, bar: 2, baz: 3) end } x.report('method_block do end') { n.times do method_block do end end } x.report('method_block{}') { n.times do method_block{ } end } x.report('[1/100] drb_remote_obj.method_no_args') { (n / 100).times do drb_remote_obj.method_no_args end } x.report('[1/100] drb_remote_obj.method_default') { (n / 100).times do drb_remote_obj.method_default end } x.report('[1/100] drb_remote_obj.method_a1') { (n / 100).times do drb_remote_obj.method_a1(1) end } x.report('[1/100] drb_remote_obj.method_a2') { (n / 100).times do drb_remote_obj.method_a2(1, 2) end } x.report('[1/100] drb_remote_obj.method_a3') { (n / 100).times do drb_remote_obj.method_a3(1, 2, 3) end } x.report('[1/100] drb_remote_obj.method_args') { (n / 100).times do drb_remote_obj.method_args(1, 2, 3) end } x.report('[1/100] drb_remote_obj.method_keywords') { (n / 100).times do drb_remote_obj.method_keywords(foo: 1, bar: 2, baz: 3) end } x.report('[1/100] drb_remote_obj.method_block do end') { (n / 100).times do drb_remote_obj.method_block do end end } x.report('[1/100] drb_remote_obj.method_block{}') { (n / 100).times do drb_remote_obj.method_block{ } end } end
測定
実行結果の抜粋:
1,000,000 times. user system total real method_no_args 0.457672 0.000000 0.457672 ( 0.457662) method_default 0.627657 0.000000 0.627657 ( 0.627657) method_a1 0.475510 0.000004 0.475514 ( 0.475568) method_a2 0.481245 0.000000 0.481245 ( 0.481259) method_a3 0.494288 0.000000 0.494288 ( 0.494388) method_args 1.146560 0.000000 1.146560 ( 1.146752) method_keywords 2.559685 0.000000 2.559685 ( 2.560266) method_block do end 0.670567 0.000000 0.670567 ( 0.670818) method_block{} 0.670467 0.000000 0.670467 ( 0.670500) [1/100] drb_remote_obj.method_no_args 1.482313 0.306498 1.788811 ( 4.789675) [1/100] drb_remote_obj.method_default 1.541902 0.272193 1.814095 ( 4.933442) [1/100] drb_remote_obj.method_a1 1.682313 0.262968 1.945281 ( 5.310548) [1/100] drb_remote_obj.method_a2 1.936925 0.170552 2.107477 ( 5.754095) [1/100] drb_remote_obj.method_a3 1.891366 0.351507 2.242873 ( 6.103683) [1/100] drb_remote_obj.method_args 2.018824 0.219010 2.237834 ( 6.194996) [1/100] drb_remote_obj.method_keywords 1.924781 0.241488 2.166269 ( 5.759805) [1/100] drb_remote_obj.method_block do end 6.226273 0.649228 6.875501 ( 12.205400) [1/100] drb_remote_obj.method_block{} 6.274446 0.661823 6.936269 ( 12.281795)
Rubyの素のメソッド呼び出しが0.5μs~数μsに対して、dRubyのメソッド呼び出しは500μs~千μs (0.5ms~1ms)かかるようだ。
環境情報
パフォーマンス測定で使った環境は次の通り。
$ ruby -v ruby 2.5.3p105 (2018-10-18 revision 65156) [armv7l-linux-eabihf] $ uname -a Linux gut 4.14.74-v7+ #1149 SMP Mon Oct 8 17:39:42 BST 2018 armv7l GNU/Linux $ cat /proc/cpuinfo processor : 0 model name : ARMv7 Processor rev 4 (v7l) BogoMIPS : 38.40 Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4 processor : 1 model name : ARMv7 Processor rev 4 (v7l) BogoMIPS : 38.40 Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4 processor : 2 model name : ARMv7 Processor rev 4 (v7l) BogoMIPS : 38.40 Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4 processor : 3 model name : ARMv7 Processor rev 4 (v7l) BogoMIPS : 38.40 Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x0 CPU part : 0xd03 CPU revision : 4 Hardware : BCM2835 Revision : a020d3 Serial : 00000000a40d8075