Closed s-yata closed 9 years ago
実験には, Wikipedia を Pandoc でテキスト化したものを Body
として,整数を二つ追加した上で Json 化したものを使います.
Length
は Body
の長さ, Random
は擬似乱数により生成された値 [0, 100) を入れてあります.
基本的に, Wikipedia の段落が一つのレコードに対応しています.
{"Body":"地理学(ちりがく、、、)は...と称される[1]。","Length":471,"Random":81}
{"Body":"元来は農耕や戦争、...求められるようになった。","Length":324,"Random":87}
{"Body":"地理学の歴史","Length":18,"Random":47}
{"Body":"...「近代地理学の父」...","Length":96,"Random":59}
{"Body":"地理学誕生の地は、...重要性を説いた。","Length":925,"Random":81}
CPU は Core i7 4558U 2.8GHz (up to 3.3GHz) です. VMWare 上の Ubuntu 14.04 にて実行します.
以下のようにします.
count := 0
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
// Store data into Groonga DB.
values := scanner.Text()
values = strings.Replace(values, "'", "\\'", -1)
command := "load --table Table --values '[" + values + "]'"
if err := ctx.Send(command); err != nil {
log.Fatalln("goroonga error:", err)
}
_, err := ctx.Receive()
if err != nil {
log.Fatalln("goroonga error:", err)
}
count++
}
以下のようにします.
count := 0
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
// Store data into Grnxx DB.
var row Row
if err := json.Unmarshal(scanner.Bytes(), &row); err != nil {
log.Fatalln("json error:", err)
}
rowID, err := table.InsertRow(nil)
if err != nil {
log.Fatalln("grnxx error:", err)
}
if err := bodyColumn.Set(rowID, grnxx.Text(row.Body)); err != nil {
log.Fatalln("grnxx error:", err)
}
if err := lengthColumn.Set(rowID, grnxx.Int(row.Length)); err != nil {
log.Fatalln("grnxx error:", err)
}
if err := randomColumn.Set(rowID, grnxx.Int(row.Random)); err != nil {
log.Fatalln("grnxx error:", err)
}
count++
}
プログラムにバグがあったので,以下の結果は無効です.
time
にて計測した実行結果を以下に示します.
Groonga only は Groonga のみへの入力をおこなった結果, Parse only は Json のパースのみをおこなった結果(参考程度), Grnxx only は Grnxx への入力のみをおこなった結果, Groonga + Grnxx は両方への入力をおこなった結果です.
Groonga only | Parse only | Grnxx only | Groonga + Grnxx | |
---|---|---|---|---|
real | 25.995s | 4.184s | 4.803s | 34.723s |
user | 18.913s | 4.088s | 4.816s | 26.794s |
sys | 6.739s | 0.174s | 0.193s | 7.747s |
Groonga, Grnxx ともに索引なしでの結果です. Groonga 側に全文検索を担当させるのであれば,転置索引の構築が加わるため, Grnxx への入力にかかる時間は影響が小さくなるものと予想されます.
現状の結果でも,想定している用途からすると特に問題なさそうですが,ほかに何か調べておくべきことはないか検討してみました.
取り急ぎは思い付きませんが,何か思い付いたときか,ほかのテストに関連して調査できるときなどにおこないます.
[0, 10,000)
[0, 1)
Groonga only は Groonga のみへの入力をおこなった結果, Grnxx only は Grnxx への入力のみをおこなった結果, Groonga + Grnxx は両方への入力をおこなった結果です.
Groonga only | Grnxx only | Groonga + Grnxx | |
---|---|---|---|
real | 12.931s | 6.005s | 21.201s |
user | 12.634s | 6.005s | 20.738s |
sys | 0.278s | 0.219s | 0.419s |
Groonga, Grnxx ともに索引なしでの結果です. 修正前の結果と比べて差はかなり縮まっていますが, Grnxx の方が速いようです.
一行ずつ入れるのであれば,形式による違いはほとんどなさそうに思えます. 念のために試しますが,複数行をまとめて入力しないと効果はあまり期待できません.
ドキュメントを見る限り,もっとも速そうなのは, --columns
でカラムを指定し,値を配列で渡すというものです.
複数行に分ける形式(標準入力形式)については,個別に Send()
, Receive()
が必要らしいので,微妙な気がします.
ただし,エスケープは省略できるので,二行目にデータを連結して渡すのはアリかもしれません.
Goroonga で複数行をまとめて入力するケースについては, #155 で調査します.
load
で複数行をまとめて入力すれば,ロード時間(変換込み)を 1/3 程度に短縮できるようです.そのため,複数行をまとめて入力できる状況であれば, Goroonga の方が Grnxx より速くなる可能性があります.
とはいえ, Grnxx のロードで時間がかかっているのは JSON から Grnxx 形式に変換するところなので,入力のフォーマット次第なところがあります.
同じクエリを Goroonga と Groonga コマンドで試してみたところ,同じくらいの時間で終了しました. Goroonga の方が少し不利かと思っていたのですが, Groonga コマンドは各クエリの実行時間を表示するのが影響しているかもしれません. とはいえ,深追いするほどのことではないと思います.
概要
Goroonga を使って Groonga にデータを投入するのと, Go wrapper を使って Grnxx にデータを投入するのにかかる時間を比較します.