groonga / grnxx

groonga++
Other
7 stars 0 forks source link

Goroonga のロード時間を調べる #155

Closed s-yata closed 9 years ago

s-yata commented 9 years ago

概要

Goroonga では Groonga のコマンド(load)を使ってデータを入力できます. Groonga の load コマンドがサポートしている書式について,どの書式を使えば効率的にデータを入力できるのかを調査します.

今回は Goroonga を使っての計測ですが,内部では grn_ctx_send/recv() を使っているため, Groonga コマンドにも同様の傾向が見られるはずです.

s-yata commented 9 years ago

書式

Groonga の load コマンドには,いくつかの書式があります.

まずは --values によりデータも一緒に指定する方法ですが, --columns を指定するか,単純な配列と連想配列のどちらを使うかによって細分化できます.

# Form1A
> load --table Table --columns ColA,ColB --values '[[ValA,ValB],[ValA,ValB],...]'
# Form1B
> load --table Table --values '[[\"ColA\",\"ColB\"],[ValA,ValB],[ValA,ValB],...]'
# Form1C
> load --table Table --values '[{\"ColA\":ValA,\"ColB\",ValB},{\"ColA\":ValA,\"ColB\",ValB},[ValA,ValB],...]'

それから, --values を使わずにデータを別に渡す方法があります. load ... のデータを除く部分をまず grn_ctx_send() で送り,データはつづけて grn_ctx_send() により送ることになります(Goroonga では Query() を 2回).

# Form2A
> load --table Table --columns ColA,ColB
> [[ValA,ValB],[ValA,ValB],...]
# Form2B
> load --table Table
> '[["ColA","ColB"],[ValA,ValB],[ValA,ValB],...]'
# Form2C
> load --table Table
> '[{"ColA":ValA,"ColB",ValB},{"ColA":ValA,"ColB",ValB},[ValA,ValB],...]'

また,コマンドの呼び出しにはオーバーヘッドがあるので,コマンド一つで何行かまとめて入力する方が効率的になるはずです.

s-yata commented 9 years ago

データ

実験に用いたデータは #152 とよく似ていますが,少しだけ変更しました(Length を削除).

table_create Table TABLE_NO_KEY
column_create Table Body --type Text
column_create Table RInt --type Int64
column_create Table RFloat --type Float

実験環境

s-yata commented 9 years ago

一行ずつ入力

まずは一行ずつ入力するときに最適な書式を見つけるべく比較をおこないました. 結果は以下の表にまとめてあります.

conversionload コマンドを生成するのに要した時間です. loadgoroonga.Context.Query() の実行に要した時間です.

conversion load
Form1A 3.191s 11.711s
Form1B 3.064s 11.890s
Form1C 2.953s 11.552s
Form2A 2.781s 13.223s
Form2B 2.887s 12.804s
Form2C 2.662s 12.520s

以上の結果から, Form1A/B/C の方が良さそうなことがわかります. Form1A/B/C の中では,ほとんど差がありません. 一行ずつ入力するのであれば,どれを選んでもかまわないでしょう.

Form2A/B/C については,エスケープが不要になって conversion が少し短くなっているものの, load がそれ以上に長くなっているのでオススメできません.

s-yata commented 9 years ago

複数行ずつ入力

以下において, #rows は一度の Query() でまとめて入力した行数を示しています.

変換(conversion)にかかる時間(秒単位)

変換に要した時間を表にしたものが以下になります. #rows を大きくするほどコマンドが少なくてよいため,変換にかかる時間が短くなっています. ただし,一行ずつ入力するときと比べても,それほど大きな差はありません.

#rows Form1A Form1B Form1C Form2A Form2B Form2C
1 3.255 4.083 3.267 2.764 3.679 2.761
2 2.712 3.256 2.919 2.431 2.891 2.557
3 2.641 3.015 2.709 2.290 2.625 2.347
4 2.552 2.831 2.580 2.216 2.501 2.295
5 2.480 2.680 2.566 2.170 2.371 2.240
6 2.414 2.648 2.448 2.157 2.299 2.142
7 2.373 2.553 2.398 2.151 2.225 2.162
8 2.339 2.437 2.396 2.089 2.179 2.060
9 2.285 2.475 2.370 2.071 2.128 2.093
10 2.323 2.421 2.293 2.079 2.154 2.014
20 2.194 2.296 2.237 1.945 1.989 1.952
30 2.093 2.225 2.199 1.894 1.894 1.857
40 2.144 2.118 2.168 1.832 1.891 1.850
50 2.063 2.194 2.158 1.855 1.899 1.754
60 2.101 2.083 2.153 1.851 1.854 1.749
70 2.069 2.120 2.100 1.796 1.837 1.744
80 2.155 2.186 2.094 1.787 1.832 1.841
90 2.134 2.026 2.107 1.810 1.813 1.758
100 2.064 2.066 2.100 1.816 1.772 1.745

入力(load)にかかる時間(秒単位)

入力に要した時間を表にしたものが以下になります. #rows を大きくするほど時間を短縮できることがわかります. 入力を数行ずつにまとめるだけでも効率化できるようです. また, 3 行以上をまとめるときは Form2A/B/C の方が効率的なようです. Form2A/B/C の中で比べると Form2A/B が優れています.

#rows Form1A Form1B Form1C Form2A Form2B Form2C
1 12.331 12.420 12.138 13.939 13.416 13.881
2 7.774 7.609 8.188 8.029 7.880 8.266
3 6.073 6.029 6.758 6.128 5.871 6.437
4 5.261 5.263 6.020 4.916 4.820 5.424
5 4.775 4.724 5.626 4.313 4.208 4.938
6 4.459 4.549 5.280 3.881 3.843 4.405
7 4.227 4.200 5.124 3.641 3.566 4.224
8 4.076 4.033 4.902 3.333 3.302 3.973
9 3.915 3.896 4.817 3.222 3.173 3.871
10 3.833 3.782 4.762 3.061 3.015 3.681
20 3.377 3.301 4.272 2.414 2.458 3.122
30 3.135 3.110 4.109 2.209 2.199 2.926
40 3.047 3.439 4.043 2.100 2.153 2.830
50 3.068 2.989 3.981 2.049 2.016 2.741
60 2.955 2.967 3.979 1.985 2.011 2.710
70 2.906 2.960 3.905 1.988 1.939 2.664
80 3.023 2.916 3.905 1.934 1.918 2.750
90 2.921 2.937 3.883 1.902 2.113 2.630
100 2.862 2.862 3.893 1.888 1.988 2.678
s-yata commented 9 years ago

複数行ずつ入力

表をグラフにしただけです.

変換(conversion)にかかる時間(秒単位)

conversion-time

入力(load)にかかる時間(秒単位)

load-time

s-yata commented 9 years ago

追加調査

念のために,転置索引を有りにしても差が出るかを調べておこうと思います.

s-yata commented 9 years ago

複数行入力の効果(転置索引あり)

転置索引を以下のようにして作成し,あらためて入力(load)にかかる時間を計測してみました.

table_create Terms TABLE_PAT_KEY|KEY_NORMALIZE ShortText --default_tokenizer TokenBigram
column_create Terms BodyIndex COLUMN_INDEX|WITH_POSITION Table Body

以下の表は入力時間(秒単位)をまとめたものです. #rows を大きくすることで時間を短縮できていますが,転置索引があるときは気にするほどの差ではないかもしれません. 運用上の制約があることを考えれば,労力の方が大きいように思います.

#rows Form1A Form1B Form1C Form2A Form2B Form2C
1 67.923 66.103 66.424 67.160 66.443 66.336
10 56.071 54.544 57.693 54.771 53.714 57.455
100 52.717 52.440 53.678 53.095 56.031 51.400