rabbit-slide-kou-rubykaigi-2014 2014.9.20.0

Sign up to get free protection for your applications and to get access to all the features.
data/note.md ADDED
@@ -0,0 +1,355 @@
1
+ # 原稿
2
+
3
+ はじめまして、須藤と言います。
4
+
5
+ RubyKaigi 2014も今日で最終日です。みなさん、RubyKaigi 2014を楽しめましたか?
6
+
7
+ 残りのセッションはあと2つになりました。
8
+ 最後のセッションは今日の英語でのキーノートです。そして、このセッションは今日の日本語でのキーノートです。(注: 冗談です。)
9
+
10
+
11
+ それでは始めましょうか。
12
+
13
+ 今日はRubyの使い方を3種類紹介します。最初は細かいことまでいろいろ話そうと思ったのですが、資料をまとめていたら細かく話していると時間がなくなることがわかったので、細かいことは少しだけにとどめています。細かいことを聞きたくなったら遠慮なく発表が終わった後に声をかけてください。
14
+
15
+
16
+ みなさん知らないと思うので最初に少しお知らせをします。
17
+
18
+ 私はクリアコードという会社の社長なのですが、そのクリアコードという会社はRubyKaigi 2014のシルバースポンサーをしています。シルバースポンサー一覧の一番上に載っているのは一番最初にシルバースポンサーの申し込みをしたからです。
19
+
20
+
21
+ さて、最初に今日の話のゴールを説明します。話し終わった後にこれらが実現できていたら今日の私の話は成功です。
22
+
23
+ 今日はRubyの使い方を3種類紹介します。今日の話を聞いて、みなさんがこれらの使い方をできるようになるわけではありませんが、こういう使い方もできるんだということを知ってもらいたいと思っています。
24
+
25
+ 1つめはハイレベルなインターフェイスを実装するという使い方です。
26
+
27
+ 2つめはグルー言語としてRubyを使うという使い方です。
28
+
29
+ 3つめはRubyを組み込んで使うという使い方です。
30
+
31
+ いざというときにみなさんがこれらの使い方を思い出せるようになっていればよいなぁと思っています。そうすれば、今よりもいろんな場面でRubyを活かせるはずです。Rubyを活かして楽しくプログラムを書ける分野が広がるといいなぁと思います。
32
+
33
+
34
+ それぞれの使い方の対象者は違っています。後の方ほど難易度が高くなっています。なお、今日はCRubyを使っている人が対象で、JRubyを使っている人は対象外です。JRubyの場合はC/C++と書いているところがJavaになるくらいで同じような傾向になると思います。
35
+
36
+ まず、ハイレベルなインターフェイスを実装するという使い方の対象者はピュアなRubyistです。ここでいうピュアというのはRubyだけを使ってプログラムを書いているという意味で、書いている人がピュアかどうかは関係ありません。
37
+
38
+ 次の、グルー言語としてRubyを使うという使い方の対象者は、必要ならC/C++も書けるよ、くらいのRubyistです。
39
+
40
+ 最後のRubyを組み込んで使うという使い方は、普段からRubyも書くしC/C++も書くよ、というRubyistです。
41
+
42
+ 徐々に対象者の人数は減っていくと思います。
43
+
44
+ ちなみに、自分がピュアRubyistだと思っている人は手を上げてみてください。(ニヤニヤしながら)ふーん。(注:アドリブです。)
45
+
46
+
47
+ それでは順に説明していきます。今日は、Rubyで分散全文検索エンジンを実装する、場合を例にして説明します。Distributed full-text search engineは長いので、これ以降の資料ではDFTSEと略して書いています。話すときは省略しないで話すのでわからなくなることはないはずです。
48
+
49
+ ところで、Rubyで分散全文検索エンジンを実装したことがある人はいますか?みなさん、ないですね。それでは自分が実装するとしたらどうするかということを新鮮な気持ちで考えながら聞いてください。
50
+
51
+
52
+ 分散全文検索エンジンの動きを単純化して図にするとこうなります。
53
+
54
+ 分散全文検索エンジンの中にはたくさんの全文検索エンジンがあります。全文検索処理をリクエストされたら、それを1つ以上の全文検索エンジンに分配して全文検索処理をします。それぞれの全文検索エンジンで全文検索をしたらそれを集めて1つにまとめて結果を返します。
55
+
56
+ 単純化するとこんな動きをするものが分散全文検索エンジンです。
57
+
58
+
59
+ どうして分散全文検索エンジンを例にするかというと、今、私はDroongaという分散全文検索エンジンを作っているからです。
60
+
61
+
62
+ それでは1つめの使い方、ハイレベルなインターフェイスを実装する使い方を説明します。対象者はピュアRubyistです。Rubyだけを使ってプログラムを書いている人ですね。
63
+
64
+
65
+ ハイレベルなインターフェイスはローレベルな機能を上のレイヤーに提供します。このとき、詳細を隠蔽してシンプルなAPIにしたり、より使いやすいAPIにすることが期待されます。使いにくいAPIでは、ローレベルな機能をそのまま使ってもいいじゃん、となり、うれしさが少ないからです。
66
+
67
+
68
+ 図にするとこんなイメージです。
69
+
70
+ ローレベルな機能を使いやすくする便利なAPIをRubyで作る、という使い方です。
71
+
72
+
73
+ みなさん、Droongaを知らないと思うので、もっと有名なソフトウェアを例にしてどういう使い方かを説明します。
74
+
75
+ 例えば、Vagrantです。Vagrantは開発環境を簡単に構築するためのツールです。Vagrantの設定ファイルはRubyスクリプトで記述します。設定ファイルではベースとするイメージはどれにするとか、メモリはどのくらいにする、などを指定すればいい感じに開発環境を作ってくれます。具体的にどうやってメモリを設定しているかを気にする必要はありません。便利ですね。
76
+
77
+ もうひとつの例はActive Recordです。Active RecordはRDBMSのデータをオブジェクト指向らしいAPIで操作できるAPIを提供しています。普通のオブジェクトの属性にアクセスするように書けばテーブルのカラムにアクセスできます。実際はSQLを使ってデータにアクセスしていますが、その詳細をいい感じに隠蔽して便利に使えるAPIを提供しています。
78
+
79
+ このように、ハイレベルなインターフェイスを作るという使い方はRubyが得意とする使い方の1つです。Rubyだけで実現できることも多いのでピュアRubyistでもできます。すでにこのように使っている人も多いでしょう。抽象化のバリアー(abstraction barrier)という概念を知っている人ならピンときやすいと思います。
80
+
81
+
82
+ では、Droonga、分散全文検索エンジンでは、どのあたりにこのハイレベルなインターフェイスを作るという使い方をするとよいでしょうか。
83
+
84
+ Droongaではメッセージングシステムでこの使い方をしています。
85
+
86
+
87
+ 図にするとこうです。
88
+
89
+ 全文検索リクエストを受け取って、それをいい感じに分配して、それを集めて返す処理です。
90
+
91
+
92
+ このメッセージングシステムを使うとユーザーはどうやって分散して検索しているかを気にする必要はありません。お願いしたらあとはいい感じに検索してくれます。便利ですね。
93
+
94
+
95
+ さて、このメッセージングシステムのそれぞれの処理の性能特性を考えてみましょう。
96
+
97
+ どのように分散して検索するかを考えるところが一番性能に効いてきます。いい感じに分散できたときと、無駄に分散してしまったときでは100倍以上の差が出ることもあります。
98
+
99
+ リクエストを分配するところは主にネットワーク処理が性能に影響します。
100
+
101
+ レスポンスを集めるところは主にCPUを使う処理とネットワーク処理が性能に影響します。
102
+
103
+
104
+ ということで、どのように分散するかが大事ということです。
105
+
106
+ もしかしたら、新しく分散方法を考えなければいけないかもしれないですし、既存の分散方法を改良しないといけないかもしれません。
107
+
108
+ そのためには、手早く動くものを作って、測定して、フィードバックを得るということを繰り返すというやり方が向いています。
109
+
110
+ Rubyは手早く動くものを作ることがしやすい言語なのでこのような開発方法に向いていますね。
111
+
112
+ なお、Droongaのように速度を改善するという場合ではなく、使い勝手を改善するという場合もこのようなフィードバックループは有効です。なので、ハイレベルなインターフェイスを実装するという使い方はRubyが得意な使い方です。
113
+
114
+
115
+ 次の使い方はグルー言語として使う使い方です。対象者はC/C++も書けるRubyistです。
116
+
117
+ C/C++も書けるRubyistな人はどのくらいいますか?
118
+
119
+
120
+ グルー言語として使う場合、2つのパターンがあります。
121
+
122
+ 1つめは他の言語の機能をRubyから使えるようにするという機能です。バインディングや拡張ライブラリーと呼ばれているものです。
123
+
124
+ 2つめは複数の機能を組み合わせる機能です。
125
+
126
+
127
+ 実例はまたActive RecordとVagrantです。
128
+
129
+ Active RecordはMySQLへアクセスする機能を得るためにmysql2 gemというライブラリーを利用しています。このmysql2 gemがグルーです。
130
+
131
+ Vagrantは仮想マシンを作ったり作った仮想マシンをセットアップする機能など、外部の機能をつなぎあわせています。Vagrantの主な仕事がグルーです。
132
+
133
+
134
+ どうしてグルー言語として使うかということ、既存の機能を再利用したいからです。
135
+
136
+
137
+ グルーの作り方は3つあります。
138
+
139
+ 1つめはmysql2 gemのように拡張ライブラリーを作る方法です。
140
+
141
+ 2つめはVagrantのように外部のコマンドを実行する方法です。
142
+
143
+ 3つめは外部のサービスを使うクライアントを実装する方法です。例えば、Twitterクライアント機能を実装する、といったことです。
144
+
145
+
146
+ Droongaの中でもいろんなグルーを使っています。
147
+
148
+ 既存のGroongaという全文検索エンジンを使うためにRroongaというバインディングを使っています。
149
+
150
+ 既存の高性能なイベントループを機能を使うためにCool.ioというバインディングを使っています。
151
+
152
+ Droongaクラスター内のノードを管理するためにSerfを使っています。Serfはコマンドを実行して使っています。
153
+
154
+ Rroongaの使い方についてもう少し説明します。
155
+
156
+
157
+ Droongaの中ではそれぞれのノードで全文検索エンジンを使うためにRroongaを使っています。
158
+
159
+
160
+ Droongaの中で全文検索エンジンは速くなければいけません。そして全文検索はCPUが性能に影響する処理です。メモリーも影響するんですが、メモリーに載らなくなったら性能的に負けなのでそこは前提と考えた方が適切です。
161
+
162
+
163
+ 全文検索機能は速くなければいけないので、Rroongaも速くなければいけません。Groonga自体は速いのですが、Rroongaを経由したら遅くなった、はまずいのです。
164
+
165
+ では、どうすればRroongaも速くなるか、ポイントをいくつか紹介します。
166
+
167
+ まず、重い処理はCで処理するようにします。このとき、RubyらしいAPIをできるだけ維持することが望ましいです。RubyらしいAPIについては去年のRubyKaigiで話したので興味がある人は探してみてください。るびまにも記事を書きました。
168
+
169
+ 次のポイントはメモリーをできるだけ割り当てないことです。これは、内部でキャッシュ用のバッファーを持つことになります。
170
+
171
+ 次のポイントはマルチプロセス処理です。Rubyは1プロセスでは複数のCPUコアを使い切れないのでマルチプロセス構成にします。なお、Groongaは複数プロセスからデータベースを開けるので、マルチプロセス構成と相性がよいです。
172
+
173
+ 今日は最初の重い処理はCで処理するについて少し説明します。
174
+
175
+
176
+ Rroongaでは全文検索はこのように書きます。
177
+
178
+ データベースを開いて、テーブルを持ってきて、descriptionカラムに対して"Ruby"という文字列で全文検索するというコードです。Rubyでは「=~」がマッチ演算子なので同じ演算子で全文検索できるようにしています。
179
+
180
+ このコードは重い処理をCで実行しています。
181
+
182
+
183
+ それでは、参考のために重い処理もRubyでやるコードを見てみましょう。
184
+
185
+ データベースを開いてテーブルを持ってくるところまでは同じです。find_allはおなじみのEnumerableのメソッドで、「/Ruby/」は正規表現でのマッチです。
186
+
187
+ このコードは各レコードに対してRubyのブロックを評価しています。この各レコードに対して実行する処理が重い処理です。
188
+
189
+
190
+ それでは、最初のコードがどのように実行されるかを見てみましょう。
191
+
192
+ 実は、ブロックの中身は1度しか評価されません。1度実行して、それをGroonga用の式にコンパイルします。それを使ってGroonga内で検索処理を実行します。各レコードに対する処理はすべてCで行われます。
193
+
194
+
195
+ 図にするとこうです。
196
+
197
+ ブロックの中で式を作って、それを使ってGroonga内部で評価して結果を返す、という流れです。
198
+
199
+
200
+ これでホントに速いのか気になりますよね。ベンチマークを取ってきました。
201
+
202
+ Rubyから使ったときとCから使ったときの速度を比較します。
203
+
204
+
205
+ なお、Cで書くとこうなります。
206
+
207
+
208
+ 結果はこの通り、0.2msくらいしか変わりません。これならRubyから使っても十分速いと言えます。
209
+
210
+
211
+ それでは、最後の使い方、Rubyを組み込む使い方です。対象者は普段からRubyもC/C++も書いているというRubyistです。
212
+
213
+ どのくらいいますか?
214
+
215
+ Rubyを組み込んだことがある人はどのくらいいますか?rubyコマンドは除きます。
216
+
217
+
218
+ Rubyを組み込むとは2種類の使い方があります。
219
+
220
+ アプリケーションやライブラリーの中で使うエンジンとしてRubyインタプリターを使うという使い方です。
221
+
222
+ アプリケーションやライブラリーのAPIや設定にRubyを使うという使い方です。インターフェイスとしてRubyを使う使い方です。
223
+
224
+
225
+ 例を示します。
226
+
227
+ 内部のエンジンとして使っているのはGroongaで、これはこれから説明します。
228
+
229
+ インターフェイスとして使っているのはVIMです。私はEmacs派なのでよく知らないんですが、RubyでVIMの設定をできたりするんですよね?
230
+
231
+
232
+ なお、GroongaにRubyを組み込んでいるというのはDroongaから見るとこうなります。
233
+
234
+ Droonga自体はRubyで書かれていてその中でRroongaを使っていてそれ経由でGroongaを使っていてさらにその中にmrubyがいます。
235
+
236
+
237
+ 組み込むRuby実装はCRubyもmrubyも使えます。私は両方組み込んだことがあるので、その経験から違いを説明します。
238
+
239
+ CRubyは普段使っているRubyの機能をすべて使えることが魅力です。ただ、それほど組み込まれることを想定していないので、初期化するとシグナルハンドラーを設定するなどします。なので、初期化時などにひと工夫必要です。
240
+
241
+ mrubyは1つのプロセスに複数のインスタンスを作れることが魅力です。シグナルハンドラーを設定したりしないのでわりとすんなり組み込むことができます。ただ、普段使っている機能がなかったりするのでいつも通り書くとうまく動かないことがあります。
242
+
243
+ Groongaではスレッドごとにインタプリターを作りたかったのとフットプリントが小さくしたかったのでmrubyを使っています。
244
+
245
+
246
+ Groongaではmrubyをどのように使っているかを説明します。
247
+
248
+ 今はクエリーオプティマイザーとして使っています。
249
+
250
+ 今後はGroongaのコマンドやプラグインを書くAPIとしても使っていこうと思っています。
251
+
252
+ クエリーオプティマイザーについて少し説明します。
253
+
254
+
255
+ クエリーオプティマイザーとはどのように検索するかを考える処理です。
256
+
257
+ これが結構面倒な処理です。
258
+
259
+ その後に実行する全文検索に比べたら軽い処理です。
260
+
261
+ データに依存するので動的な要素もあります。
262
+
263
+
264
+ このような範囲検索をするクエリーを考えます。
265
+
266
+
267
+ 単純な実装を考えます。まず200より小さいレコードを集めます。次に100より大きいレコードを集めます。それらの共通部分を求めます。これで結果がでます。
268
+
269
+
270
+ これはデータが多いと遅くなります。
271
+
272
+
273
+ 最適化するとこうなります。最初から下限と上限を指定して検索します。これならデータが多くなっても大丈夫です。
274
+
275
+
276
+ では、組み込んでホントに割り合うのでしょうか。計測してみましょう。
277
+
278
+
279
+ 計測するのは次の2項目です。
280
+
281
+ 1つはmrubyを組み込んだことによるオーバーヘッドです。
282
+
283
+ もう1つは最適化した結果どのくらい速くなるかです。
284
+
285
+
286
+ オーバーヘッドです。
287
+
288
+ クエリーが複雑なほど解析する時間がかかります。複雑化どうかはざっくり言えば項目が多いかどうかです。mrubyを組み込むことで0.Xms秒増えました。全文検索処理はXms以上かかるので、これくらいなら許容範囲です。
289
+
290
+
291
+ 次はどのくらい高速になったかです。
292
+
293
+ 100レコードでもmrubyを組み込んだときの方が速いです。レコード数が多くなるとその差は明らかです。オーバーヘッドが許容範囲で、最適化が効くと十分高速になるので割にあいますね。
294
+
295
+
296
+ 注意
297
+
298
+ 今日は触れていませんが、組み込むのはけっこういろいろやることがあります。バインディングを書いたり、ビルドシステムにmrubyのビルドを組み込んだりいろいろあります。
299
+
300
+ mruby部分のテストをどうするの?デバッグは?gdbは使えないよ、みたいなことがあります。
301
+
302
+ 興味がある人は後で話してください。
303
+
304
+
305
+ まとめです。
306
+
307
+
308
+ Rubyの使い方を3種類紹介しました。
309
+
310
+ 1つめはハイレベルなインターフェイスを実装するという使い方です。
311
+
312
+ 2つめはグルー言語として使うという使い方です。
313
+
314
+ 3つめはRubyを組み込むという使い方です。
315
+
316
+
317
+ ハイレベルなインターフェイスを実装するという使い方はピュアRubyist向けです。
318
+
319
+ 便利なインターフェイスを提供する使い方です。
320
+
321
+ Rubyの柔軟性が役に立ちます。
322
+
323
+
324
+ グルー言語として使うのはC/C++も書けるRubyist向けです。
325
+
326
+ 既存の機能を再利用する使い方です。
327
+
328
+ 速さが必要ならできるだけCで処理を動かすようにしましょう。
329
+
330
+
331
+ Rubyを組み込む使い方はRubyと同じくらいC/C++も書くRubyist向けです。
332
+
333
+ Rubyを使って面倒なプログラムをしなくても済みます。
334
+
335
+
336
+ ただ、面倒を避けるためにそこそこの作業が必要になるので、本当に割に合うかはよく考えてください。
337
+
338
+ 割に合うならとても役立ちます。
339
+
340
+ 興味がある人は私に相談してください。
341
+
342
+
343
+ ということで私の話は終わりです。
344
+
345
+ 最後にお知らせです。
346
+
347
+ クリアコードはシルバースポンサーです。なので、少し宣伝していいよね。
348
+
349
+ 開発者を募集しています。こんなRubyの使い方に興味のある人は検討してみてください。
350
+
351
+ 私はリーダブルコードという本の解説を書いたのですが、その縁もあってリーダブルコードワークショップというのを開催する予定です。日々リーダブルコードを書きたい人は検討してみてください。
352
+
353
+ どっちもチラシを配っています。私に声を書けても説明しますし、クリアコードのサイトをみても載っています。
354
+
355
+ Groongaに興味を持った人は11/29(いい肉の日)にイベントがあるので予定を開けておいてください。同じ日に地域Ruby会議もあると思いますが、よく考えてみてください。
@@ -0,0 +1 @@
1
+ include_theme("clear-code")
@@ -0,0 +1,501 @@
1
+ = Three Ruby usages
2
+
3
+ : subtitle
4
+ Inside Droonga
5
+ : author
6
+ Kouhei Sutou
7
+ : institution
8
+ ClearCode Inc.
9
+ : content-source
10
+ RubyKaigi 2014
11
+ : date
12
+ 2014/09/20
13
+ : allotted-time
14
+ 25m
15
+ : theme
16
+ .
17
+
18
+ = Silver sponsor
19
+
20
+ # image
21
+ # src = images/clear-code-is-silver-sponsor.png
22
+ # relative_width = 100
23
+
24
+ == slide property
25
+
26
+ : enable-title-on-image
27
+ false
28
+
29
+ = Goal
30
+
31
+ * You know three Ruby usages
32
+ * High-level interface
33
+ * Glue
34
+ * Embed
35
+ * You can remember them later
36
+
37
+ = Targets
38
+
39
+ * High-level interface
40
+ * Pure Rubyists
41
+ * Glue
42
+ * Rubyists who can write C/C++
43
+ * Embed
44
+ * Rubyists who also write C/C++
45
+
46
+ = Case study
47
+
48
+ # blockquote
49
+ Implement distributed full-text search engine in Ruby
50
+
51
+ (('note:Abbreviation: DFTSE = Distributed Full-Text Search Engine'))
52
+
53
+ = DFTSE?
54
+
55
+ # image
56
+ # src = images/distributed-full-text-search-engine.svg
57
+ # relative_width = 80
58
+
59
+ == slide property
60
+
61
+ : enable-title-on-image
62
+ false
63
+
64
+ = Why do we use DFTSE?
65
+
66
+ I'm developing Droonga\n
67
+ (('note:(A DFTSE implementation in Ruby)'))\n
68
+ 😃
69
+
70
+ = High-level interface
71
+
72
+ (('tag:center'))Three Ruby usages
73
+
74
+ * ((*High-level interface*))
75
+ * Target: Pure Rubyists
76
+ * Glue
77
+ * Embed
78
+
79
+ = High-level interface
80
+
81
+ * Provides\n
82
+ lower layer feature to\n
83
+ higher layer
84
+ * With simpler/convenience API
85
+
86
+ = High-level interface
87
+
88
+ # image
89
+ # src = images/high-level-interface.svg
90
+ # relative_height = 95
91
+
92
+ == slide property
93
+
94
+ : enable-title-on-image
95
+ false
96
+
97
+ = Example
98
+
99
+ # image
100
+ # src = images/high-level-interface-examples.svg
101
+ # relative_width = 100
102
+
103
+ == slide property
104
+
105
+ : enable-title-on-image
106
+ false
107
+
108
+ = Droonga: High-level IF
109
+
110
+ (('tag:center'))DFTSE components
111
+
112
+ * Full-text search engine
113
+ * ((*Messaging system*))
114
+ * Cluster management
115
+ * Process management
116
+
117
+ = Messaging system
118
+
119
+ # image
120
+ # src = images/droonga-messaging-system.svg
121
+ # relative_width = 80
122
+
123
+ == slide property
124
+
125
+ : enable-title-on-image
126
+ false
127
+
128
+ = Messaging system
129
+
130
+ * Provides\n
131
+ distributed search feature
132
+ * Plan how to search
133
+ * Distribute requests
134
+ * Merge responses
135
+ * Users don't know details
136
+
137
+ = Characteristic
138
+
139
+ * Plan how to search
140
+ * May speed up/down over 100 times
141
+ * Distribute requests
142
+ * Network bound operation
143
+ * Merge responses
144
+ * CPU and network bound operation
145
+
146
+ = Point
147
+
148
+ * Algorithm is important
149
+ * Need to find new/existing better algorithm
150
+ * "Rapid prototype and measure" feedback loop is helpful
151
+ * Ruby is good at rapid dev.
152
+
153
+ = Glue
154
+
155
+ (('tag:center'))Three Ruby usages
156
+
157
+ * High-level interface
158
+ * ((*Glue*))
159
+ * Target:\n
160
+ Rubyists who can write C/C++
161
+ * Embed
162
+
163
+ = Glue
164
+
165
+ # image
166
+ # src = images/glue.svg
167
+ # relative_width = 80
168
+
169
+ == slide property
170
+
171
+ : enable-title-on-image
172
+ false
173
+
174
+ = Example
175
+
176
+ # image
177
+ # src = images/glue-examples.svg
178
+ # relative_width = 80
179
+
180
+ == slide property
181
+
182
+ : enable-title-on-image
183
+ false
184
+
185
+ = Why do we glue?
186
+
187
+ * Reuse existing features
188
+
189
+ = How to glue
190
+
191
+ * Use external library
192
+ * (('wait'))Implement bindings (('note:(mysql2 gem)'))
193
+ * Use external command
194
+ * (('wait'))Spawn command (('note:(Vagrant)'))
195
+ * Use external service
196
+ * (('wait'))Implement client
197
+
198
+ = Glue in Droonga
199
+
200
+ * ((*Rroonga*)): Groonga bindings
201
+ * Groonga: FTSE C library (('note:(and server)'))
202
+ * Cool.io: libev bindings
203
+ * libev: Event loop C library\n
204
+ (('note:(Based on I/O multiplexing and non-blocking I/O)'))
205
+ * Serf: Clustering tool (('note:(in Droonga)'))
206
+
207
+ = Rroonga in Droonga
208
+
209
+ # image
210
+ # src = images/droonga-rroonga.svg
211
+ # relative_width = 80
212
+
213
+ == slide property
214
+
215
+ : enable-title-on-image
216
+ false
217
+
218
+ = FTSE in Droonga
219
+
220
+ * Must be fast!
221
+ * CPU bound processing
222
+
223
+ = For fast Rroonga
224
+
225
+ * ((*Do heavy processing in C*))
226
+ * Nice to have Ruby-ish API
227
+ * (('wait'))Less memory allocation
228
+ * Cache internal buffer
229
+ * (('wait'))Multiprocessing
230
+ * Groonga supports multiprocessing
231
+
232
+ = Search
233
+
234
+ # coderay ruby
235
+
236
+ Groonga::Database.open(ARGV[0])
237
+ entries = Groonga["Entries"]
238
+
239
+ entries.select do |record|
240
+ record.description =~ "Ruby"
241
+ end
242
+
243
+ = Search - Pure Ruby (ref)
244
+
245
+ # coderay ruby
246
+
247
+ Groonga::Database.open(ARGV[0])
248
+ entries = Groonga["Entries"]
249
+
250
+ entries.find_all do |record|
251
+ # This block is evaluated for each record
252
+ /Ruby/ =~ record.description
253
+ end
254
+
255
+ = Search impl.
256
+
257
+ # coderay ruby
258
+
259
+ # (2) Evaluate expression in C
260
+ entries.select do |record|
261
+ # (1) Build expression in Ruby
262
+ # This block is evaluated only once
263
+ record.description =~ "Ruby"
264
+ end
265
+
266
+ = Search impl. - Fig.
267
+
268
+ # image
269
+ # src = images/rroonga-search.svg
270
+ # relative_width = 80
271
+
272
+ == slide property
273
+
274
+ : enable-title-on-image
275
+ false
276
+
277
+ = Search - Benchmark
278
+
279
+ * Ruby (('note:(It's already showed)'))
280
+ * C
281
+
282
+ = Search - C
283
+
284
+ # coderay c
285
+
286
+ grn_obj *expr;
287
+ grn_obj *variable;
288
+ const gchar *filter = "description @ \"Ruby\"";
289
+ grn_obj *result;
290
+
291
+ GRN_EXPR_CREATE_FOR_QUERY(&ctx, table, expr, variable);
292
+ grn_expr_parse(&ctx, expr,
293
+ filter, strlen(filter), NULL,
294
+ GRN_OP_MATCH, GRN_OP_AND,
295
+ GRN_EXPR_SYNTAX_SCRIPT);
296
+ result = grn_table_select(&ctx, table, expr, NULL, GRN_OP_OR);
297
+ grn_obj_unlink(&ctx, expr);
298
+ grn_obj_unlink(&ctx, result);
299
+
300
+ = Search - Benchmark
301
+
302
+ (('tag:center'))Ruby impl. is fast enough 😃
303
+
304
+ # RT
305
+
306
+ Impl., Elapsed time
307
+
308
+ C, 0.6ms
309
+ Ruby, 0.8ms
310
+
311
+ (('tag:center'))\n
312
+ (('note:(Full-text search with "Ruby" against 72632 records)'))
313
+
314
+ = Embed
315
+
316
+ (('tag:center'))Three Ruby usages
317
+
318
+ * High-level interface
319
+ * Glue
320
+ * ((*Embed*))
321
+ * Target:\n
322
+ Rubyists who also write C/C++
323
+
324
+ = Embed
325
+
326
+ # image
327
+ # src = images/embed.svg
328
+ # relative_width = 90
329
+
330
+ == slide property
331
+
332
+ : enable-title-on-image
333
+ false
334
+
335
+ = Examples
336
+
337
+ # image
338
+ # src = images/embed-examples.svg
339
+ # relative_width = 90
340
+
341
+ == slide property
342
+
343
+ : enable-title-on-image
344
+ false
345
+
346
+ = Embed in Droonga
347
+
348
+ # image
349
+ # src = images/droonga-mruby.svg
350
+ # relative_height = 100
351
+
352
+ == slide property
353
+
354
+ : enable-title-on-image
355
+ false
356
+
357
+ = CRuby vs. mruby
358
+
359
+ * CRuby
360
+ * Full featured!
361
+ * Signal handler isn't needed 😞
362
+ * mruby
363
+ * Multi-interpreters in a process!
364
+ * You may miss some features 😞
365
+
366
+ = mruby in Groonga
367
+
368
+ * Query optimizer
369
+ * Command interface (plan)
370
+ * High-level interface!
371
+ * Plugin API (plan)
372
+
373
+ = Query optimizer
374
+
375
+ * Plan how to search
376
+ * It's a bother 😞
377
+ * Light operation than FTS
378
+ * Depends on data\n
379
+ (('note:(Choose effective index, use table scan and so on)'))
380
+
381
+ = Example
382
+
383
+ rank < 200 && rank > 100
384
+
385
+ = Simple impl.
386
+
387
+ # image
388
+ # src = images/range-search-simple.svg
389
+ # relative_height = 90
390
+
391
+ == slide property
392
+
393
+ : enable-title-on-image
394
+ false
395
+
396
+ = Simple impl.
397
+
398
+ * Slow against\n
399
+ many out of range data
400
+
401
+ = Optimized impl.
402
+
403
+ # image
404
+ # src = images/range-search-optimized.svg
405
+ # relative_width = 90
406
+
407
+ == slide property
408
+
409
+ : enable-title-on-image
410
+ false
411
+
412
+ = Is embedding reasonable?
413
+
414
+ Measure
415
+
416
+ = Measure
417
+
418
+ * mruby overhead
419
+ * Speed-up by optimization
420
+
421
+ = Overhead
422
+
423
+ (('tag:center'))Small overhead: Reasonable😃
424
+
425
+ # RT
426
+
427
+ (('# conds')), mruby, Elapsed
428
+
429
+ 1, ○, 0.24ms
430
+ 1, ×, 0.16ms
431
+ 4, ○, 0.45ms
432
+ 4, ×, 0.19ms
433
+
434
+ = Speed-up
435
+
436
+ (('tag:center'))Fast for many data:Reasonable😃
437
+
438
+ # RT
439
+
440
+ (('# records')), mruby, nom mruby
441
+
442
+ 1000, 0.29ms, 0.31ms
443
+ 10000, 0.31ms, 2.3ms
444
+ 100000, 0.26ms, 21.1ms
445
+ 1000000, 0.26ms, 210.2ms
446
+
447
+ = Note
448
+
449
+ * Embedding needs many works
450
+ * Write bindings, import mruby your build system and ...
451
+ * How to test your mruby part?
452
+ * And how to debug?
453
+
454
+ = Conclusion
455
+
456
+ = Conclusion 1
457
+
458
+ * Describe three Ruby usages
459
+ * (('wait'))High-level interface
460
+ * (('wait'))Glue
461
+ * (('wait'))Embed
462
+
463
+ = Conclusion 2
464
+
465
+ * High-level interface
466
+ * Target: Pure Rubyists
467
+ * Provides lower layer feature to higher layer w/ usable interface
468
+ * Ruby's flexibility is useful
469
+
470
+ = Conclusion 3
471
+
472
+ * Glue
473
+ * Target:\n
474
+ Rubyists who can write C/C++
475
+ * Why: Reuse existing feature
476
+ * To be fast, do the process in C
477
+
478
+ = Conclusion 4
479
+
480
+ * Embed
481
+ * Target:\n
482
+ Rubyists who also write C/C++
483
+ * Why:\n
484
+ Avoid bother programming by Ruby
485
+
486
+ = Conclusion 5
487
+
488
+ * Embed
489
+ * Is it reasonable for your case?
490
+ * You need many works
491
+ * Very powerful\n
492
+ if your case is reasonable😃
493
+
494
+ = Announcement
495
+
496
+ * ClearCode Inc.
497
+ * A silver sponsor
498
+ * Is recruiting
499
+ * Will do readable code workshop
500
+ * The next Groonga conference
501
+ * It's held at 11/29