おおいしつかさ


旅行とバイクとドライブと料理と宇宙が好き。
Ubie Discoveryのプログラマ。
Share:  このエントリーをはてなブックマークに追加

Ruby1.9を試すその1 - ネイティブスレッド

Ruby1.9からThreadがネイティブスレッドを使うようになります。といっても、VMレベルでロックされるようなので、同時に実行されるスレッドは常にひとつです。ただし、IO関連のブロック機能を備えたシステムコールは同時に実行されるようです。

以下のような簡単なIOテストを実行してみました。

require 'benchmark'  

threads = []  
Benchmark.bm do |x|  
  x.report do  
    1000.times do |i|  
      threads << Thread.new(i) do |t_i|  
        File.open("#{t_i}.count", "w") do |f|  
          1000.times {|i| f.puts i}  
        end  
      end  
    end  
  end  
end  
threads.each {|t| t.join}  

結果。

[tsukasa@ubuntu] $ ruby1.8 aa.rb 
      user     system      total        real  
  2.090000   0.490000   2.580000 (  2.579993)  
[tsukasa@ubuntu] $ rm -f *.count  
[tsukasa@ubuntu] $ ruby aa.rb  
      user     system      total        real  
  0.750000   0.170000   0.920000 (  0.939997)  
[tsukasa@ubuntu] $ [                     

それから、IOなしのテストをやってみます。

require 'benchmark'  

threads = []  
Benchmark.bm do |x|  
  x.report do  
    1000.times do |i|  
      threads << Thread.new(i) do |t_i|  
        (1..10000).inject(0) {|result,i| result *= i}  
      end  
    end  
  end  
end  
threads.each {|t| t.join}  

結果。

[tsukasa@ubuntu] $ ruby1.8 aa.rb  
      user     system      total        real  
 14.890000   4.950000  19.840000 ( 19.839974)  
[tsukasa@ubuntu] $ ruby aa.rb  
      user     system      total        real  
  1.530000   0.090000   1.620000 (  1.620000)  

全然性能が違いますね。コンテキストスイッチの処理で大きく差が出ているのかな。

Threadを介さずにやってみましょう。

require 'benchmark'  

threads = []  
Benchmark.bm do |x|  
  x.report do  
    (1..1000000).inject(0) {|result,i| result *= i}  
  end  
end  
threads.each {|t| t.join}  

結果。

[tsukasa@ubuntu] $ ruby1.8 aa.rb  
      user     system      total        real  
  1.430000   0.470000   1.900000 (  1.899998)  
[tsukasa@ubuntu] $ ruby aa.rb  
      user     system      total        real  
  0.140000   0.000000   0.140000 (  0.140000)  

なるほど。VM化による性能の差が大きく出ているみたいです。すばらしい。