XPStoreというのはread-onlyの
transactionをできるようにしたPStoreです。
内部的には、read-onlyの時にはFile::LOCK_SHを使い、
そうでないときには従来通りFile::LOCK_EXを使う
という違いがあります。
このことによって、複数のプロセスから 同じファイルを参照するようなケースで 速度的に有利になることが確認されています。 特にCGIスクリプトの中から簡易データベース的に PStoreを使うような状況で効果が出るでしょう。
以下はPStore(バージョン1.6.3のRubyに添付のもの)および XPStore(バージョン0.0.0.0)を使って、 read:write = 50:1の条件で3000回のアクセスを行うプロセスを 10個並列に動かしたときの様子です。 表示は、その一つ一つのプロセスでかかった時間を gotoenさんのbenchmark.rb ではかったものです。
$ ruby test2.rb 10 PStore 50 1 3000 PStore 1.000000 0.290000 1.290000 ( 12.689074) PStore 1.020000 0.290000 1.310000 ( 12.757505) PStore 1.030000 0.220000 1.250000 ( 12.424774) PStore 1.010000 0.260000 1.270000 ( 12.207886) PStore 0.980000 0.300000 1.280000 ( 12.504196) PStore 1.040000 0.210000 1.250000 ( 12.329138) PStore 1.030000 0.190000 1.220000 ( 12.226299) PStore 1.010000 0.230000 1.240000 ( 12.320477) PStore 0.970000 0.250000 1.220000 ( 12.224091) PStore 1.020000 0.220000 1.240000 ( 12.365093) PStore: 29425 575 575 $ ruby test2.rb 10 XPStore 50 1 3000 XPStore 0.340000 0.070000 0.410000 ( 3.121789) XPStore 0.340000 0.050000 0.390000 ( 3.038229) XPStore 0.320000 0.050000 0.370000 ( 2.929975) XPStore 0.300000 0.080000 0.380000 ( 3.085453) XPStore 0.310000 0.040000 0.350000 ( 2.985765) XPStore 0.360000 0.060000 0.420000 ( 3.377134) XPStore 0.300000 0.100000 0.400000 ( 3.129535) XPStore 0.270000 0.130000 0.400000 ( 2.829846) XPStore 0.290000 0.100000 0.390000 ( 2.876644) XPStore 0.300000 0.080000 0.380000 ( 2.667300) XPStore: 29412 588 588
逆に以下のような状況(ほとんどwriteだったり、 同時にアクセスするプロセスが少ない場合)では似たようなものか、 XPStoreの方が遅くなることもあるようです。
$ ruby test2.rb 3 PStore 1 50 3000 PStore 0.990000 0.290000 1.280000 ( 3.835005) PStore 0.950000 0.310000 1.260000 ( 3.721977) PStore 0.970000 0.280000 1.250000 ( 3.721518) PStore: 194 8806 8806 $ ruby test2.rb 3 XPStore 1 50 3000 XPStore 1.090000 0.200000 1.290000 ( 3.899631) XPStore 1.080000 0.220000 1.300000 ( 4.110147) XPStore 1.120000 0.290000 1.410000 ( 4.147850) XPStore: 177 8823 8823
開発版であるRuby 1.7系ではPStoreが新しくなっていますが、 それでもXPStoreの方が速いようです。
$ ruby-beta -v test2.rb 10 PStore 50 1 3000 ruby 1.7.0 (2001-05-07) [i386-linux] ./benchmark.rb:46: warning: print (...) interpreted as method call PStore 1.000000 0.280000 1.280000 ( 13.165319) PStore 0.970000 0.290000 1.260000 ( 13.239765) PStore 1.040000 0.300000 1.340000 ( 13.327358) PStore 1.030000 0.290000 1.320000 ( 13.296780) PStore 1.060000 0.200000 1.260000 ( 13.022845) PStore 0.980000 0.240000 1.220000 ( 12.970015) PStore 1.020000 0.260000 1.280000 ( 13.249534) PStore 1.060000 0.190000 1.250000 ( 12.936891) PStore 0.950000 0.260000 1.210000 ( 12.617803) PStore 0.950000 0.370000 1.320000 ( 13.252610) PStore: 29409 591 591 $ ruby-beta -v test2.rb 10 XPStore 50 1 3000 ruby 1.7.0 (2001-05-07) [i386-linux] ./benchmark.rb:46: warning: print (...) interpreted as method call XPStore 0.320000 0.080000 0.400000 ( 3.848528) XPStore 0.300000 0.080000 0.380000 ( 3.823339) XPStore 0.290000 0.120000 0.410000 ( 3.951646) XPStore 0.360000 0.070000 0.430000 ( 3.931581) XPStore 0.300000 0.070000 0.370000 ( 3.791742) XPStore 0.300000 0.070000 0.370000 ( 3.783584) XPStore 0.360000 0.080000 0.440000 ( 3.898706) XPStore 0.300000 0.090000 0.390000 ( 3.746849) XPStore 0.290000 0.070000 0.360000 ( 3.645467) XPStore 0.340000 0.050000 0.390000 ( 3.574248) XPStore: 29383 617 617