groongaの最適化によるビルド時間への影響

> もっとgroongaを知ってもらおう!ということで週刊groongaをはじめました。毎週木曜にgroongaやmroonga、rroongaのトピックを投稿予定です。

いよいよ、[gihyo.jp](http://gihyo.jp/)さんでgroongaの隔週更新連載が始まりました!! 
第6回の記事も公開されたので、一読をおすすめします。

* [「第1回 全文検索エンジンgroongaを紹介します！」](http://gihyo.jp/dev/clip/01/groonga/0001)
* [「第2回 groongaをRuby On Railsでも使ってみた ～chikamap.comの事例から」](http://gihyo.jp/dev/clip/01/groonga/0002)
* [「第3回 すべてのMySQLユーザに高速な全文検索機能を！ - mroongaの紹介」](http://gihyo.jp/dev/clip/01/groonga/0003)
* [「第4回 rroongaを使ったソースコード検索エンジンMilkode」](http://gihyo.jp/dev/clip/01/groonga/0004)
* [「第5回 Rubyでサーバ要らずの高速全文検索！ - rroongaの紹介」](http://gihyo.jp/dev/clip/01/groonga/0005)
* [「第6回 [実録] MySQL向け全文検索エンジン「Tritonn」から「mroonga」への移行ガイド（1）」](http://gihyo.jp/dev/clip/01/groonga/0006)


連載は始まりましたが、利用事例をどんどん紹介していきたいです。(利用事例のストックが尽きたら終了してしまいます。)
groongaやmroonga、rroongaを実際に使っていて利用事例記事を書いてもいいよ、という人をまだまだ募集しています。
詳細は[groonga普及のための協力のお願い](http://sourceforge.jp/projects/groonga/lists/archive/dev/2013-February/001186.html)を参照してください。

# はじめに

オープンソースの[カラムストア機能付き全文検索エンジンgroonga](http://groonga.org/ja/)を公開しています。

最新のバージョンは2013年5月29日にリリースした[3.0.4](http://groonga.org/ja/docs/news.html#release-3-0-4)です。

今回は、groongaの最適化によるビルド時間への影響について紹介します。

# groongaのソースアーカイブについて

groongaは各種プラットフォーム向けにパッケージを提供しています。

* Debian (squeeze/wheezy/jessie/unstable)
* Ubuntu (10.04 LTS/12.04 LTS/12.10/13.04)
* CentOS 5/6
* Fedora 18
* Windows

ただ、サポートしていないプラットフォームであったり、(サポートされていても)自分でソースからビルドしたいこともあるでしょう。
修正版をすぐに試したい人向けにソースコードのアーカイブをnightlyリリースとして提供しているからです。
(これは毎日日付が変わるタイミングでスナップショットをそのままソースアーカイブとしているものです。)

nightlyリリースのダウンロード先は http://packages.groonga.org/nightly/ です。

例えば、今日は2013年6月27日なので、以下のソースアーカイブが提供されています。

* [groonga-3.0.4.2013.06.27.tar.gz](http://packages.groonga.org/nightly/groonga-3.0.4.2013.06.27.tar.gz)

groongaだけでなく、groonga-normalizer-mysql や mroonga も提供しています。

* [groonga-normalizer-mysql-1.0.4.2013.06.27.tar.gz](http://packages.groonga.org/nightly/groonga-normalizer-mysql-1.0.4.2013.06.27.tar.gz)
* [mroonga-3.04.2013.06.27.tar.gz](http://packages.groonga.org/nightly/mroonga-3.04.2013.06.27.tar.gz)

# groongaをソースからビルドする


ソースアーカイブからビルドする手順については、[2.8.2 ソースからビルド](http://groonga.org/ja/docs/install/others.html#build-from-source)として紹介しています。

簡単な手順は以下の通りです。

```
% ./configure
% make
% sudo make install
```

これを実行すると、環境によってはなかなかmakeが終わらないという状況に遭遇します。
よくあるのが、以下のソースのコンパイルが進まない、というものです。

* lib/expr.c
* lib/nfkc.c

これは実は最適化で時間がかかっているせいなのです。

# 最適化の有無とビルド時間

では、実際に最適化の有無によりビルド時間がどれほど違うのか確認してみましょう。

ビルドに使用した計算機のスペックは以下の通りです。

| 項目       | 値                                       |
|:----------|-----------------------------------------:|
| CPU       | Intel(R) Core(TM) i7-2640M CPU @ 2.80GHz |
| Memory    | 8GB |


最適化を有効にしてビルドする場合には特に ``./configure`` に指定する必要はありません。
ソースアーカイブを展開して ``./configure`` を実行するまでは以下の手順となります。

```sh
% wget http://packages.groonga.org/source/groonga/groonga-3.0.4.tar.gz
% tar xf groonga-3.0.4.tar.gz
% cd groonga-3.0.4
% ./configure
```

``./configure`` を実行するとサマリが表示されます。 ``-O2`` とあるので最適化が有効になっていることがわかります。

```
groonga 3.0.4 configuration:
-----------------------
  Compiler:              gcc
  CFLAGS:                -g -O2 -Wall -Wextra -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-sign-compare -Wno-pointer-sign -Wno-missing-field-initializers -Wformat=2 -Wstrict-aliasing=2 -Wdisabled-optimization -Wfloat-equal -Wpointer-arith -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wredundant-decls -Wwrite-strings  
  CXXFLAGS:              -g -O2 -Wall -Wextra -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-sign-compare -Wno-missing-field-initializers -Wformat=2 -Wstrict-aliasing=2 -Wdisabled-optimization -Wfloat-equal -Wpointer-arith -Wcast-align -Wredundant-decls -Wwrite-strings -fexceptions -fimplicit-templates
  Libraries:             -lz -ldl -lpthread -lm  
```

一方明示的に最適化を無効にするには以下のようにCFLAGSとCXXFLAGSを指定します。

```sh
% wget http://packages.groonga.org/source/groonga/groonga-3.0.4.tar.gz
% tar xf groonga-3.0.4.tar.gz
% cd groonga-3.0.4
% ./configure CFLAGS="-O0 -g3" CXXFLAGS="-O0 -g3"
```

``./configure`` を実行したサマリは以下の通りです。 ``-O0`` とあるので最適化が無効になっていることがわかります。

```
groonga 3.0.4 configuration:
-----------------------
  Compiler:              gcc
  CFLAGS:                -O0 -g3 -Wall -Wextra -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-sign-compare -Wno-pointer-sign -Wno-missing-field-initializers -Wformat=2 -Wstrict-aliasing=2 -Wdisabled-optimization -Wfloat-equal -Wpointer-arith -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wredundant-decls -Wwrite-strings  
  CXXFLAGS:              -O0 -g3 -Wall -Wextra -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-sign-compare -Wno-missing-field-initializers -Wformat=2 -Wstrict-aliasing=2 -Wdisabled-optimization -Wfloat-equal -Wpointer-arith -Wcast-align -Wredundant-decls -Wwrite-strings -fexceptions -fimplicit-templates
  Libraries:             -lz -ldl -lpthread -lm  
```

では、ビルドしてみましょう。
最適化ありのときのビルドにかかる時間は以下の通りでした。

```
% time make
make  836.42s user 19.29s system 97% cpu 14:41.88 total
```

一方最適化を無効にしてビルドするとビルドにかかる時間は以下の通りでした。

```
% time make
make  114.64s user 16.10s system 82% cpu 2:37.59 total
```

最適化を有効にすることで6倍近い時間がかかっていることがわかります。
ソースコードからビルドする手順としてよくある以下の手順だと最適化は有効になっているので、最適化を無効にすることでビルド時間を1/6近くへ短縮できるとも言えます。

```
% ./configure
% make
% make install
```

今回ビルドに使用したCPUはCore i7なので、複数のコアを有効活用してビルドしてみましょう。

``make -jN`` を使うとそれが実現できますね。

Core i7のコア数は以下のようにして確認できます。

```
% grep '^processor' /proc/cpuinfo | wc -l
4
```

最適化ありの``-j4``でビルドするとビルドにかかる時間は以下の通りでした。

```
% time make -j$(grep '^processor' /proc/cpuinfo | wc -l)
make -j$(grep '^processor' /proc/cpuinfo | wc -l)  1096.82s user 22.81s system 189% cpu 9:49.49 total
```

最適化なしの``-j4``でビルドするとビルドにかかる時間は以下の通りでした。

```
% time make -j$(grep '^processor' /proc/cpuinfo | wc -l)
make -j$(grep '^processor' /proc/cpuinfo | wc -l)  174.04s user 16.26s system 254% cpu 1:14.81 total
```

最適化の有無、コアの活用によってビルド時間に大きな差異があることがわかります。

| 項目       | 値                                       |
|:----------|-----------------------------------------:|
| 最適化あり(リリース版)       | 14分42秒 |
| 最適化なし    | 2分38秒 |
| 最適化あり(make -j4) | 9分50秒 |
| 最適化なし(make -j4) | 1分15秒 |

# まとめ

今回は、groongaの最適化によるビルド時間への影響について紹介しました。

プロダクション環境では(検索時間へ影響するので)最適化を無効にしたgroongaを使うことはお勧めしません。

ただ、開発環境であったりnightly版を使うなどgroongaを更新する機会が多い場合には、ビルド時間を短縮できるメリットがあるでしょう。
(最適化によってメモリを多く使うので、積んでいるメモリが少ない場合に有効かも知れません。)

通常は毎月肉の日にリリースしているパッケージを利用されることをおすすめしますが、どうしてもソースアーカイブからビルドしたいときには参考にしてみてください。

groongaに興味を持ったなら、まずは[インストール](http://groonga.org/ja/docs/install.html)して試してみてください。

groongaの基本的な動作を知るための[チュートリアル](http://groonga.org/ja/docs/tutorial.html)もあります。インストールしたら試してみてください。