修正したコードを使ってVMWare上のCouchDBサーバに対して、118,924件の郵便番号を数えた場合の速度を比較してみました。
元々のDBの構造はCSVファイルを1文書に変換したもので、詳細は 以前の記事にあります。
その他のmap/reduce関数の定義、データ取得用スクリプトは次のとおりです。
json['views']['code']['map'] = <<-MAP
function(doc) {
if(doc._id.length == 40) {
emit(doc.code, 1)
}
}
MAP
json['views'][label]['reduce'] = "_sum"
#!/usr/local/bin/ruby
# -*- coding: utf-8 -*-
require 'csv'
require 'couchdb'
require 'json'
require 'uri'
couch = Couch::Server.new("localhost","5984")
def show(couch, uri)
begin
res = couch.get(URI.escape(uri))
json = JSON.parse(res.body)
p json['group_numrows'] if json.has_key?('group_numrows')
p json['rows'].length if json.has_key?('rows')
rescue
p $!
end
end
#uri = YaCouch::DBname + '/_design/all/_view/code?group=true'
#show(couch, uri)
uri = YaCouch::DBname + '/_design/all/_view/code?group=true&group_numrows=true'
show(couch, uri)
これにtimeコマンドを使って実行速度を測ってみました。
VMWareを使うとディスクアクセスは特にホストOSのファイルキャッシュの影響を強く受ける傾向があると感じているので、何回か両方のスクリプトを実行した後に計測を始め、各2回目の結果を載せています。
Array.lengthを使って重複を取り除いたキーの数を数える方法
配列の数を数え上げるわけですが、各要素は、 {"key"=>"9998524", "value"=>1}、のような形式になっています。
118924 real 0m8.183s user 0m4.188s sys 0m3.812s
group_numrowsパラメータでCouchDBから取得する方法
この戻り値は単純で、クライアントが受け取るのは、 {"group_numrows":"118924"}の一行だけです。 スクリプトの最後の4行のコメントを変更して、同じように実行しています。
"118924" real 0m0.952s user 0m0.132s sys 0m0.052s
Array.lengthを計算しない、JSON.parseを実行しない場合の速度
スクリプトをちょっと変更して、res = couch.get(URI.escape(uri))
行の次にreturnを挿入して、すぐに戻るようにしてみました。
real 0m7.796s user 0m3.784s sys 0m3.836s
今回の環境では、ほとんどネットワークトラフィックの影響が時間に大きな影響を与えていて、JSON.parse()
自体が時間を取っているわけではない事がわかります。
まとめ
この後に実環境でも試しましたが、おおむね同じような結果になりました。
ただし、group_numrowsを使った場合の実時間が最大1.4[s]程度、配列を取得する場合の時間が最小5.7[s]程度となり、その差は縮まっています。
erlangの軽量プロセスについて、もう少し勉強して何か不備はないか確認しようと思います。
0 件のコメント:
コメントを投稿