rabbit-slide-kou-rubykaigi-2017 2017.9.18.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 56f66d64ab2afa98268d83f3b952625f45affcf9
4
+ data.tar.gz: c5b64688f7185fa0dd1a2504727f0f9f495d56a2
5
+ SHA512:
6
+ metadata.gz: 0ff5431f5f138e4ef67318343aa4bbc17bd97187715ecc2f71b105defc96fe982b9a405b944d3428192fc6d41f3f38ad5e4b644b4aead1837c5e9eabc721a40a
7
+ data.tar.gz: 6af279da5452f64a9ef449b9b500fd88e4983f582871a5d531f66ec0c38179e1c276e175a35ed2f659124af45b2952b5f4ebd1f898c9748187ac86a1b3b8c8ce
data/.rabbit ADDED
@@ -0,0 +1 @@
1
+ extension-by-cpp.rab
data/README.rd ADDED
@@ -0,0 +1,41 @@
1
+ = Improve extension API: C++ as better language for extension
2
+
3
+ Ruby's extension API is for C. This talk proposes C++ as a better language for extension API.
4
+
5
+ == License
6
+
7
+ === Slide
8
+
9
+ CC BY-SA 4.0
10
+
11
+ Use the followings for notation of the author:
12
+
13
+ * Kouhei Sutou
14
+
15
+ ==== ClearCode Inc. logo
16
+
17
+ CC BY-SA 4.0
18
+
19
+ Author: ClearCode Inc.
20
+
21
+ It is used in page header and some pages in the slide.
22
+
23
+ == For author
24
+
25
+ === Show
26
+
27
+ rake
28
+
29
+ === Publish
30
+
31
+ rake publish
32
+
33
+ == For viewers
34
+
35
+ === Install
36
+
37
+ gem install rabbit-slide-kou-rubykaigi-2017
38
+
39
+ === Show
40
+
41
+ rabbit rabbit-slide-kou-rubykaigi-2017.gem
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ require "rabbit/task/slide"
2
+
3
+ # Edit ./config.yaml to customize meta data
4
+
5
+ spec = nil
6
+ Rabbit::Task::Slide.new do |task|
7
+ spec = task.spec
8
+ spec.files += Dir.glob("images/**/*.*")
9
+ # spec.files -= Dir.glob("private/**/*.*")
10
+ spec.add_runtime_dependency("rabbit-theme-clear-code")
11
+ end
12
+
13
+ desc "Tag #{spec.version}"
14
+ task :tag do
15
+ sh("git", "tag", "-a", spec.version.to_s, "-m", "Publish #{spec.version}")
16
+ sh("git", "push", "--tags")
17
+ end
18
+
19
+ namespace :example do
20
+ desc "Build Rubex example"
21
+ task :rubex do
22
+ cd("example/rubex") do
23
+ sh("rubex", "fibonacci.rubex")
24
+ cd("fibonacci") do
25
+ ruby("execonf.rb")
26
+ sh("make")
27
+ end
28
+ end
29
+ end
30
+
31
+ desc "Build JRuby example"
32
+ task :jruby do
33
+ cd("example/jruby") do
34
+ sh("javac", "Fibonacci.java")
35
+ sh("jar", "cf", "fibonacci.jar", "Fibonacci.class")
36
+ end
37
+ end
38
+ end
data/config.yaml ADDED
@@ -0,0 +1,24 @@
1
+ ---
2
+ id: rubykaigi-2017
3
+ base_name: extension-by-cpp
4
+ tags:
5
+ - rabbit
6
+ - ruby
7
+ - extension
8
+ - c++
9
+ presentation_date: 2017-09-18
10
+ version: 2017.9.18.0
11
+ licenses:
12
+ - CC-BY-SA-4.0
13
+ slideshare_id:
14
+ speaker_deck_id:
15
+ ustream_id:
16
+ vimeo_id:
17
+ youtube_id:
18
+ author:
19
+ markup_language: :rd
20
+ name: Kouhei Sutou
21
+ email: kou@clear-code.com
22
+ rubygems_user: kou
23
+ slideshare_user: kou
24
+ speaker_deck_user:
@@ -0,0 +1,844 @@
1
+ = Improve extension API
2
+
3
+ : subtitle
4
+ C++ as better language for extension
5
+ : author
6
+ Kouhei Sutou
7
+ : institution
8
+ ClearCode Inc.
9
+ : content-source
10
+ RubyKaigi 2017
11
+ : date
12
+ 2017-09-18
13
+ : allotted-time
14
+ 35m
15
+ : theme
16
+ .
17
+
18
+ = Ad1: I'm distributing shocker combatmen to Rabbit users\n(('tag:x-small:宣伝1:Rabbitユーザーに'))\n(('tag:x-small:ショッカー戦闘員を配布中'))
19
+
20
+ # img
21
+ # src = images/shocker.jpeg
22
+ # relative_height = 110
23
+ # reflect_ratio = 0.1
24
+ # relative_margin_top = -2
25
+
26
+ == Slide properties
27
+
28
+ : enable-title-on-image
29
+ true
30
+
31
+ = Ad2: Silver sponsor
32
+
33
+ # img
34
+ # src = images/clear-code-silver-sponsor.png
35
+ # relative_height = 100
36
+ # reflect_ratio = 0.1
37
+
38
+ == Slide properties
39
+
40
+ : enable-title-on-image
41
+ false
42
+
43
+ = Ad3: Red Data Tools
44
+
45
+ * Project that provides data processing tools for Ruby\n
46
+ (('note:Ruby用のデータ処理ツール群を提供するプロジェクト'))
47
+ * https://red-data-tools.github.io/
48
+ * Workshop in afternoon break at the 2nd day (today!)\n
49
+ (('note:2日目(今日!)の午後休憩中にワークショップがあるよ!'))
50
+
51
+ = Ad4: OSS Gate
52
+
53
+ * Project that increases people who join OSS development\n
54
+ (('note:OSSの開発に継続的に参加する人を継続的に増やす取り組み'))
55
+ * https://oss-gate.github.io/
56
+
57
+ = Ad4: OSS Gate
58
+
59
+ * Ruby is an OSS\n
60
+ (('note:RubyもOSS'))
61
+ * OSS Gate wants to increase people to join Ruby itself and RubyGems development!\n
62
+ (('note:OSS GateではRuby本体の開発や各種RubyGemの開発に参加する人も増やしたい!'))
63
+
64
+ = Ad4: OSS Gate
65
+
66
+ * Now, works on Tokyo, Sapporo, Osaka and Kyoto\n
67
+ (('note:現在は東京・札幌・大阪・京都で活動中'))
68
+ * If you live at one of them, join "OSS Gate workshop"!\n
69
+ (('note:これらの地域に住んでいる人は「OSS Gateワークショップ」に参加しよう!'))
70
+
71
+ = Ad4: OSS Gate
72
+
73
+ * Wants to work on Hiroshima and other areas all over the world!\n
74
+ (('note:広島や世界中のいろんな地域で活動したい!'))
75
+ * If you're interested in increasing people who join OSS development, talk to me!\n
76
+ (('note:OSSの開発に参加する人が増えることに興味のある人は私に声をかけて!'))
77
+
78
+ = What I want to do\n(('note:やりたいこと'))
79
+
80
+ (('tag:center'))
81
+ Improve performance\n
82
+ with C/C++ libraries\n
83
+ (('note:C/C++のライブラリーを使った高速化'))
84
+
85
+ * Not wanting to create binding\n
86
+ (('note:バインディングを作りたいわけじゃない'))
87
+
88
+ = Point of improve perf\n(('note:高速化するために大事なこと'))
89
+
90
+ (('tag:center'))
91
+ Done in C/C++\n
92
+ as much as possible\n
93
+ (('note:できるだけC/C++内で完結させる'))
94
+
95
+ * Don't move between\n
96
+ C/C++ and Ruby\n
97
+ (('note:C/C++とRuby間でいったりきたりしない'))
98
+
99
+ = Example: #sum\n(('note:例:#sum'))
100
+
101
+ # coderay ruby
102
+
103
+ numbers = (1..100000).to_a
104
+ # Move between C and Ruby: 25.1ms
105
+ numbers.inject(&:+)
106
+ # Done in C: 0.5ms
107
+ # 50x faster(50倍速い)
108
+ numbers.sum
109
+
110
+ = Extension and binding\n(('note:バインディングと拡張ライブラリー'))
111
+
112
+ * Extension(('note:(拡張ライブラリー)'))
113
+ * Ruby library implemented in C\n
114
+ (('note:Cで実装されたRubyのライブラリー'))
115
+ * Binding(('note:(バインディング)'))
116
+ * Ruby library to use library implemented in other languages\n
117
+ (('note:他言語実装のライブラリを使うためのRubyのライブラリ'))
118
+
119
+ = Binding usage\n(('note:バインディングの使い方'))
120
+
121
+ * Export each API to Ruby\n
122
+ (('note:それぞれのAPIをRubyで使えるようにする'))
123
+ * Combine exported APIs in Ruby\n
124
+ (('note:バインディングが提供するAPIをRubyレベルで組み合わせる'))
125
+
126
+ = Binding usage example\n(('note:バインディングの使い方例'))
127
+
128
+ # coderay ruby
129
+
130
+ require "cairo"
131
+ include Cairo
132
+ # Combine APIs
133
+ s = PDFSurface.new("red.pdf", 10, 10) # API
134
+ context = Context.new(s) # API
135
+ context.set_source_color(:red) # API
136
+ context.paint # API
137
+ context.show_page # API
138
+ s.finish # API
139
+
140
+ = Point of improve perf\n(('note:高速化するために大事なこと'))
141
+
142
+ (('tag:center'))
143
+ Done in C/C++\n
144
+ as much as possible\n
145
+ (('note:できるだけC/C++内で完結させる'))
146
+
147
+ * Don't move between\n
148
+ C/C++ and Ruby\n
149
+ (('note:C/C++とRuby間でいったりきたりしない'))
150
+
151
+ = Improve perf example\n(('note:高速化例'))
152
+
153
+ # coderay ruby
154
+
155
+ # Don't combine APIs in Ruby
156
+ # RubyレベルでAPIを組み合わせない
157
+ ## context.set_source_color(:red) # API
158
+ ## context.paint # API
159
+ ## context.show_page # API
160
+ # Just call higher level API in Ruby
161
+ # Rubyからはもっと高レベルなAPIを呼び出す
162
+ context.show_red_page # Implemented in C
163
+ # ここはCで実装
164
+
165
+ = What I want to do\n(('note:やりたいこと'))
166
+
167
+ (('tag:center'))
168
+ Improve performance\n
169
+ with C/C++ libraries\n
170
+ (('note:C/C++のライブラリーを使った高速化'))
171
+
172
+ * Not wanting to create binding\n
173
+ (('note:バインディングを作りたいわけじゃない'))
174
+
175
+ = Use case\n(('note:高速化したい場面'))
176
+
177
+ * Machine learning\n
178
+ (('note:機械学習'))
179
+ * Combine array/matrix operations\n
180
+ (('note:配列・行列に対する演算をまとめる'))
181
+
182
+ = Raw C API\n(('note:生のC API'))
183
+
184
+ (('tag:center'))
185
+ Not bad but has some verbosities because of C\n
186
+ (('note:悪くないんだけどCなので冗長'))
187
+
188
+ * Need better approach\n
189
+ (('note:もっといい感じの方法を使いたい'))
190
+
191
+ = Requirements\n(('note:要件'))
192
+
193
+ * Easy to use C/C++ libraries\n
194
+ (('note:C/C++のライブラリーを簡単に使えること'))
195
+ * Easy to write (('note:as much as possible'))\n
196
+ (('note:できるだけ書きやすいこと'))
197
+ * Easy to debug (('note:as much as possible'))\n
198
+ (('note:できるだけデバッグしやすいこと'))
199
+
200
+ = Approaches(('note:(実現方法)'))
201
+
202
+ * Extend language to support writing extension\n
203
+ (('note:拡張ライブラリーを書けるように言語を拡張'))
204
+ * Based on not C language\n
205
+ (('note:C以外の言語を使う'))
206
+ * Provide convenient API\n
207
+ (('note:便利APIを提供'))
208
+
209
+ = Recommended approach\n(('note:オススメの実現方法'))
210
+
211
+ * Extend language to support writing extension\n
212
+ (('note:拡張ライブラリーを書けるように言語を拡張'))
213
+ * Based on not C language\n
214
+ (('note:C以外の言語を使う'))
215
+ * ((*Provide convenient API*))\n
216
+ (('note:便利APIを提供'))
217
+
218
+ = Provide convenient API\n(('note:便利なAPIを提供'))
219
+
220
+ * Rice: ((*C++*)) + Ruby
221
+ * Ext++: ((*C++*))11 + Ruby
222
+ * Boost.Python: ((*C++*)) + Python
223
+ * pybind11: ((*C++*))11 + Python
224
+
225
+ = Convenient API and C++\n(('note:便利なAPIとC++'))
226
+
227
+ * C++ can use C API directory\n
228
+ (('note:C++ではCのAPIを直接使える'))
229
+ * No need wrapper API nor libffi\n
230
+ (('note:ラッパーAPIもlibffiもいらない'))
231
+ * C++ has many convenient features\n
232
+ (('note:C++には便利機能がたくさんある'))
233
+
234
+ = Convenient API example1\n(('note:便利なAPI例1'))
235
+
236
+ # coderay ruby
237
+
238
+ # Ruby: Normal
239
+ class Sample
240
+ def hello
241
+ "Hello"
242
+ end
243
+ end
244
+
245
+ = Convenient API example1\n(('note:便利なAPI例1'))
246
+
247
+ # coderay ruby
248
+
249
+ # Ruby: No syntax sugar
250
+ Sample = Class.new do
251
+ define_method(:hello) do
252
+ "Hello"
253
+ end
254
+ end
255
+
256
+ = Convenient API example1\n(('note:便利なAPI例1'))
257
+
258
+ # coderay cpp
259
+
260
+ // C++: Ext++
261
+ #include <ruby.hpp>
262
+ extern "C" void Init_sample(void) {
263
+ rb::Class("Sample"). // class Sample in Ruby
264
+ define_method("hello", // def hello in Ruby
265
+ [](VALUE self) { // lambda {|| "Hello"} in Ruby
266
+ return rb_str_new_static("Hello");
267
+ });
268
+ }
269
+
270
+ = Convenient API example1\n(('note:便利なAPI例1'))
271
+
272
+ # coderay c
273
+
274
+ /* C */
275
+ #include <ruby.h>
276
+ static VALUE rb_sample_hello(VALUE self) {
277
+ return rb_str_new_static("Hello");
278
+ }
279
+ void Init_sample(void) {
280
+ VALUE sample = rb_define_class("Sample", rb_cObject);
281
+ rb_define_method(sample, "hello", rb_sample_hello, 0);
282
+ }
283
+
284
+ = Convenient API example2\n(('note:便利なAPI例2'))
285
+
286
+ # coderay cpp
287
+
288
+ // C++: Rice
289
+ #include <rice/Class.hpp>
290
+ static const char * // Not VALUE! (Auto convert)
291
+ rb_sample_hello(Rice::Object self) {
292
+ return "Hello";
293
+ }
294
+ extern "C" void Init_sample() {
295
+ Rice::define_class("Sample").
296
+ define_method("hello", &rb_sample_hello);
297
+ }
298
+
299
+ = Convenient C++ API1\n(('note:便利なC++ API1'))
300
+
301
+ * Default arguments(('note:(デフォルト引数)'))
302
+ * Parent class is omittable\n
303
+ (('note:RubyのAPIのように親クラスを省略可能'))
304
+ * Template(('note:(テンプレート)'))
305
+ * Auto C/C++ <-> Ruby convert\n
306
+ (('note:C/C++↔Ruby間の自動変換'))
307
+
308
+ = Convenient API example3
309
+
310
+ # coderay cpp
311
+
312
+ // C++11
313
+ #include <iostream>
314
+ #include <xtensor/xarray.hpp>
315
+ int main(void) {
316
+ xt::xarray<double> array = {1.0, 2.0, 3.0};
317
+ // Type deduction. Operator overloading.
318
+ auto result = (array + 2.0) * 3.0; // element-wise ops
319
+ for (const auto &element : result) { // result.each {}
320
+ std::cout << element << std::endl; // 9 12 15
321
+ }
322
+ return 0;
323
+ }
324
+
325
+ = Convenient C++ API2\n(('note:便利なC++ API2'))
326
+
327
+ * auto: Type deduction(('note:(型推論)'))
328
+ * Simpler code\n
329
+ (('note:コードがシンプルになる'))
330
+ * Range-based for loop(('note:(範囲forループ)'))
331
+ * Simpler code\n
332
+ (('note:コードがシンプルになる'))
333
+
334
+ = C++ based API: Pros1\n(('note:C++ベースのAPI:長所1'))
335
+
336
+ (('tag:center'))
337
+ Easy to write than C\n
338
+ (('note:Cより書きやすい'))
339
+
340
+ * Require C++11 or later\n
341
+ (('note:C++11以降なら'))
342
+
343
+ = C++ based API: Pros2\n(('note:C++ベースのAPI:長所2'))
344
+
345
+ (('tag:center'))
346
+ Easy to use for C API users\n
347
+ (('note:既存のC APIを使っている人なら使いやすい'))
348
+
349
+ * Can use C directly incl macro\n
350
+ (('note:マクロも含めてCの機能を直接使える'))
351
+ * Don't need to migrate to all convenient API at once\n
352
+ (('note:一気に書き換えるのではなく徐々に移行できる'))
353
+
354
+ = C++ based API: Pros3\n(('note:C++ベースのAPI:長所3'))
355
+
356
+ (('tag:center'))
357
+ Easy to debug for C API users\n
358
+ (('note:既存のC APIを使っている人ならデバッグしやすい'))
359
+
360
+ * Can use GDB/LLDB directly\n
361
+ (('note:GDB/LLDBを直接使える'))
362
+ * GDB/LLDB have built-in C++ support\n
363
+ (('note:GDB/LLDBは組み込みでC++をサポート'))
364
+
365
+ = C++ based API: Pros4\n(('note:C++ベースのAPI:長所4'))
366
+
367
+ (('tag:center'))
368
+ Easy to optimize\n
369
+ (('note:最適化しやすい'))
370
+
371
+ * [Feature #13434] better method definition in C API\n
372
+ (('note:Cのメソッド定義APIの改良'))
373
+
374
+ = Better method definition\n(('note:メソッド定義の改良'))
375
+
376
+ * Metadata for optimization\n
377
+ (('note:最適化のためにメタデータを付与'))
378
+ * e.g.: Reduce memory allocations\n
379
+ (('note:例:メモリーアロケーションを減らす'))
380
+ * Lazy method definition\n
381
+ (('note:必要になるまでメソッド定義を遅らせる'))
382
+ * e.g.: Reduce start-up time\n
383
+ (('note:例:起動時間の高速化'))
384
+
385
+ = Argument metadata\n(('note:引数のメタデータ'))
386
+
387
+ # coderay ruby
388
+
389
+ class Hello
390
+ # Default argument is just for
391
+ # example. Other metadata will
392
+ # be more useful for optimization.
393
+ def hello(name, message="world")
394
+ end
395
+ end
396
+
397
+ = Argument metadata\n(('note:引数のメタデータ'))
398
+
399
+ # coderay cpp
400
+
401
+ // Rice
402
+ cHello.
403
+ define_method(
404
+ "hello",
405
+ &hello,
406
+ (Rice::Arg("name"), // ↓Default
407
+ Rice::Arg("message")="world"));
408
+
409
+ = Lazy method definition\n(('note:遅延メソッド定義'))
410
+
411
+ # coderay ruby
412
+
413
+ class X
414
+ def a; end # Not define yet
415
+ def b; end # Not define yet
416
+ end
417
+ x = X.new
418
+ x.a # Define #a and #b
419
+
420
+ = Lazy method definition\n(('note:遅延メソッド定義'))
421
+
422
+ # coderay c
423
+
424
+ /* One of new C API ideas */
425
+ struct rb_method_entries entries[] = {
426
+ "a", ...,
427
+ "b", ...,
428
+ };
429
+ /* The definitions aren't defined at once. */
430
+ /* They are defined when the next method call. */
431
+ rb_define_method_with_table(rb_cX, entries);
432
+
433
+ = Lazy method definition\n(('note:遅延メソッド定義'))
434
+
435
+ # coderay c
436
+
437
+ // C++ implementation sample
438
+ {
439
+ rb::Class("X").
440
+ // Don't call rb_define_method() yet.
441
+ define_method("a", ...).
442
+ // Don't call rb_define_method() yet.
443
+ define_method("b", ...);
444
+ // Destructor is called.
445
+ // Call rb_define_method_with_table()
446
+ // in destructor.
447
+ }
448
+
449
+ = Lazy method definition\n(('note:遅延メソッド定義'))
450
+
451
+ # coderay c
452
+
453
+ // Ext++ implementation is just for test
454
+ rb::Class("X").
455
+ // Call rb_define_method() immediately.
456
+ define_method("a", ...).
457
+ // Don't call rb_define_method() in
458
+ // the following define_method()s.
459
+ enable_lazy_define_method().
460
+ // Don't call rb_define_method() yet.
461
+ define_method("b", ...);
462
+
463
+ = Lazy method definition\n(('note:遅延メソッド定義'))
464
+
465
+ # coderay ruby
466
+
467
+ # Define only benchmark code in Ruby.
468
+ # Real benchmark code is in C++.
469
+ n = 10000
470
+ Bench = Class.new do
471
+ n.times do |i|
472
+ define_method("method#{i}") do
473
+ end
474
+ end
475
+ end
476
+
477
+ = Lazy method definition\n(('note:遅延メソッド定義'))
478
+
479
+ # coderay ruby
480
+
481
+ # Call benchmark code in Ruby.
482
+ # Real benchmark code is in C++.
483
+ n = 10000
484
+ bench = Bench.new
485
+ n.times do |i|
486
+ bench.__send__("method#{i}")
487
+ end
488
+
489
+ = Lazy method definition\n(('note:遅延メソッド定義'))
490
+
491
+ # RT
492
+
493
+ Type, Define only, Called
494
+
495
+ Normal, 0.005675s, 0.005625s
496
+ Lazy, 0.001142s, 0.005674s
497
+
498
+ (('tag:center'))
499
+ 5x faster when any methods aren't called\n
500
+ (('note:メソッドが呼ばれなければ5倍速い'))
501
+
502
+ = C++ based API: Cons1\n(('note:C++ベースのAPI:短所1'))
503
+
504
+ (('tag:center'))
505
+ C++ is difficult\n
506
+ (('note:C++は難しい'))
507
+
508
+ * e.g.: Template\n
509
+ (('note:たとえばテンプレート'))
510
+ * Easy to write unreadable code\n
511
+ (('note:簡単にリーダブルじゃないコードを書ける'))
512
+
513
+ = C++ based API: Cons2\n(('note:C++ベースのAPI:短所2'))
514
+
515
+ (('tag:center'))
516
+ Slower build\n
517
+ (('note:ビルドが遅い'))
518
+
519
+ * It may reduce try&error cycle\n
520
+ (('note:試行錯誤しにくくなるかも'))
521
+
522
+ = C++ based API: Problem\n(('note:C++ベースのAPI:課題'))
523
+
524
+ (('tag:center'))
525
+ Exception\n
526
+ (('note:例外'))
527
+
528
+ * Ruby exception breaks C++ RAII (destructor)\n
529
+ (('note:Rubyの例外発生→C++のRAII(デストラクター)が動かない'))
530
+ * Because it uses setjmp/longjmp\n
531
+ (('note:Rubyの例外はsetjmp/longjmpを使っているから'))
532
+
533
+ = Exception: Solution\n(('note:例外:解決法'))
534
+
535
+ (1) Rescue Ruby exception\n
536
+ (('note:Rubyの例外をrescue'))
537
+ (2) Throw C++ exception\n
538
+ (('note:C++の例外にしてthrow'))
539
+ (3) Re-raise the Ruby exception\n
540
+ (('note:安全な場所でRubyの例外を再raise'))
541
+
542
+ = Conclusion\n(('note:まとめ'))
543
+
544
+ * C++ based API is useful\n
545
+ (('note:C++ベースのAPIは便利'))
546
+ * For writing ext uses C/C++ library\n
547
+ (('note:C/C++のライブラリを使う拡張ライブラリを書くとき'))
548
+ * For optimizing w/ easy to use API\n
549
+ (('note:例:使いやすいAPIを維持したまま最適化するとき'))
550
+
551
+ = Appendix\n(('note:付録'))
552
+
553
+ (('tag:center'))
554
+ Introduce easy to write extension approaches\n
555
+ (('note:拡張ライブラリーを簡単に実装する方法を紹介'))
556
+
557
+ * The following contents are used only when time is remained\n
558
+ (('note:以降の内容は時間が残っている場合だけ使う'))
559
+
560
+ = Approaches(('note:(実現方法)'))
561
+
562
+ * Extend language to support writing extension\n
563
+ (('note:拡張ライブラリーを書けるように言語を拡張'))
564
+ * Based on not C language\n
565
+ (('note:C以外の言語を使う'))
566
+ * Provide convenient API\n
567
+ (('note:便利APIを提供'))
568
+
569
+ = Extend language\n(('note:言語を拡張'))
570
+
571
+ * Rubex: Extended Ruby\n
572
+ (('note:Rubex:Rubyを拡張'))
573
+ * Cython: Extended Python\n
574
+ (('note:Cython:Pythonを拡張'))
575
+
576
+ = How to run\n(('note:動かし方'))
577
+
578
+ * Compile code for extended language to C\n
579
+ (('note:拡張言語で書かれたコードをCにコンパイル'))
580
+ * Build compiled C code\n
581
+ (('note:コンパイルされたCコードをビルド'))
582
+ * Load the built extension\n
583
+ (('note:ビルドした拡張ライブラリーを読み込む'))
584
+
585
+ = Extended syntax\n(('note:拡張された構文'))
586
+
587
+ * Type information\n
588
+ (('note:型情報を書ける'))
589
+ * C code snippet\n
590
+ (('note:Cのコードを書ける'))
591
+
592
+ = How to run: Rubex\n(('note:Rubexの動かし方'))
593
+
594
+ # coderay ruby
595
+ # fibonacci.rubex
596
+ class Fibonacci
597
+ # "int" is type information
598
+ def compute(int n)
599
+ # ...
600
+ end
601
+ end
602
+
603
+ = How to run: Rubex\n(('note:Rubexの動かし方'))
604
+
605
+ # coderay console
606
+ % rubex fibonacci.rubex
607
+ % cd fibonacci
608
+ % ruby extconf.rb
609
+ % make
610
+
611
+ = How to run: Rubex\n(('note:Rubexの動かし方'))
612
+
613
+ # coderay ruby
614
+ require_relative "fibonacci.so"
615
+ p Fibonacci.new.compute(100)
616
+
617
+ = Extend language: Pros1\n(('note:拡張言語:長所1'))
618
+
619
+ (('tag:center'))
620
+ Friendly syntax for base language users\n
621
+ (('note:ベースの言語のユーザーにはなじみやすい構文'))
622
+
623
+ * Most syntaxes are same\n
624
+ (('note:構文の大部分は同じだから'))
625
+
626
+ = Extend language: Pros\n(('note:拡張言語:長所2'))
627
+
628
+ (('tag:center'))
629
+ Easy to migrate from base lang\n
630
+ (('note:ベースの言語からの移行が容易'))
631
+
632
+ * Because upper compatibility\n
633
+ (('note:上位互換だから'))
634
+ * Code for base language works without modification\n
635
+ (('note:ベースの言語で書かれたコードは変更なしで動く'))
636
+
637
+ = Extend language: Pros\n(('note:拡張言語:長所3'))
638
+
639
+ (('tag:center'))
640
+ Don't require large C knowledge\n
641
+ (('note:そんなにCの知識は必要ない'))
642
+
643
+ * Most codes can be written with base language knowledge\n
644
+ (('note:コードの大部分はベースの言語の知識で書ける'))
645
+
646
+ = Extend language: Cons1\n(('note:拡張言語:短所1'))
647
+
648
+ (('tag:center'))
649
+ You realize that it's not friendly syntax when you use it\n
650
+ (('note:使うとそんなになじみやすい文法ではないと気づく'))
651
+
652
+ * Small differences will confuse you\n
653
+ (('note:小さな違いがいろいろあってわかりにくい'))
654
+
655
+ = Extend language: Cons2\n(('note:拡張言語:短所2'))
656
+
657
+ (('tag:center'))
658
+ Difficult to debug\n
659
+ (('note:デバッグが難しい'))
660
+
661
+ * Need base language, extend language and C knowledge\n
662
+ (('note:ベースの言語の知識も拡張言語の知識もCの知識も必要'))
663
+
664
+ (('note:Cython has GDB integration to solve this problem'))\n
665
+ (('note:Cythonはこの問題を解決するためにGDB用の便利機能を提供'))
666
+
667
+ = Extend language: Cons3\n(('note:拡張言語:短所2'))
668
+
669
+ (('tag:center'))
670
+ Need many works to maintain\n
671
+ (('note:(For maintainers, not for users)'))\n
672
+ (('note:(ユーザーではなくメンテナーが)メンテナンスが大変'))
673
+
674
+ * Base language introduces a new syntax then extend language should implement it\n
675
+ (('note:ベースの言語が新しい構文を導入→拡張言語でも実装'))
676
+
677
+ = Based on not C language\n(('note:C言語以外をベースにする'))
678
+
679
+ * JRuby: Java + Ruby
680
+ * Helix: Rust + Ruby
681
+
682
+ = How to run: JRuby\n(('note:JRubyでの動かし方'))
683
+
684
+ # coderay java
685
+ // Fibonacci.java
686
+ public class Fibonacci {
687
+ public long[] compute(int n) {
688
+ // ...
689
+ }
690
+ }
691
+
692
+ = How to run: JRuby\n(('note:JRubyでの動かし方'))
693
+
694
+ # coderay console
695
+ % javac Fibonacci.java
696
+ % jar cf fibonacci.jar Fibonacci.class
697
+
698
+ = How to run: JRuby\n(('note:JRubyでの動かし方'))
699
+
700
+ # coderay ruby
701
+ require "fibonacci.jar"
702
+ java_import "Fibonacci"
703
+ p Fibonacci.new.compute(100)
704
+
705
+ = Based on not C: Pros1\n(('note:C言語以外をベースにする:長所1'))
706
+
707
+ (('tag:center'))
708
+ Easy to write than C\n
709
+ (('note:Cより書きやすい'))
710
+
711
+ * Simpler syntax\n
712
+ (('note:洗練された構文'))
713
+ * Rich features than C\n
714
+ (('note:Cより機能が多い'))
715
+
716
+ = Based on not C: Pros2\n(('note:C言語以外をベースにする:長所2'))
717
+
718
+ (('tag:center'))
719
+ Can use libraries in base language\n
720
+ (('note:ベース言語のライブラリーを使える'))
721
+
722
+ * Major languages have many libraries\n
723
+ (('note:広く使われている言語はライブラリーも多い'))
724
+
725
+ = Based on not C: Cons1\n(('note:C言語以外をベースにする:短所1'))
726
+
727
+ (('tag:center'))
728
+ Need base language knowledge\n
729
+ (('note:ベース言語の知識が必要'))
730
+
731
+ * Java for JRuby(('note:(JRubyならJava)'))
732
+ * Rust for Helix(('note:(HelixならRust)'))
733
+
734
+ = Based on not C: Cons2\n(('note:C言語以外をベースにする:短所2'))
735
+
736
+ (('tag:center'))
737
+ May need C knowledge\n
738
+ (('note:(When Ruby implementation is MRI)'))\n
739
+ (('note:Rubyの実装がMRIならCの知識が必要かもしれない'))
740
+
741
+ * Base language wraps Ruby C API\n
742
+ (('note:ベースの言語はRubyのC APIをラップしている'))
743
+ * e.g.: (({sys::RSTRING_PTR})) on Helix\n
744
+ (('note:例:Helixならsys::RSTRING_PTRがラップしたAPI'))
745
+
746
+ = Based on not C: Cons3\n(('note:C言語以外をベースにする:短所3'))
747
+
748
+ (('tag:center'))
749
+ May need many works to maintain\n
750
+ (('note:(When Ruby implementation is MRI)'))\n
751
+ (('note:Rubyの実装がMRIならメンテナンスが大変かも'))
752
+
753
+ * Ruby introduces a new API then base language may need to implement it\n
754
+ (('note:Rubyが新しいAPIを追加→ベース言語でも実装?'))
755
+ * e.g.: (({rb_gc_adjust_memory_usage()}))
756
+
757
+ = Provide convenient API\n(('note:便利なAPIを提供'))
758
+
759
+ * Rice: C++ + Ruby
760
+ * Ext++: C++ + Ruby
761
+ * Boost.Python: C++ + Python
762
+ * pybind11: C++11 + Python
763
+
764
+ = How to run: Rice\n(('note:Riceの動かし方'))
765
+
766
+ # coderay cpp
767
+
768
+ #include <rice/Class.hpp>
769
+
770
+ static const char * // Not VALUE!
771
+ rb_sample_hello(Rice::Object self) {
772
+ return "Hello";
773
+ }
774
+ extern "C" void Init_sample() {
775
+ Rice::define_class("Sample").
776
+ define_method("hello", &rb_sample_hello);
777
+ }
778
+
779
+ = How to run: Rice\n(('note:Riceの動かし方'))
780
+
781
+ # coderay ruby
782
+
783
+ # extconf.rb
784
+ require "mkmf-rice"
785
+ create_makefile("sample")
786
+
787
+ = How to run: Rice\n(('note:Riceの動かし方'))
788
+
789
+ # coderay console
790
+
791
+ % ruby extconf.rb
792
+ % make
793
+
794
+ = How to run: Rice\n(('note:Riceの動かし方'))
795
+
796
+ # coderay ruby
797
+
798
+ require_relative "sample.so"
799
+ p Sample.new.hello
800
+ # => "Hello"
801
+
802
+ = Provide C++ API: Pros\n(('note:C++ APIを提供:長所'))
803
+
804
+ Omit\n
805
+ (('note:省略'))
806
+
807
+ = Provide C++ API: Cons\n(('note:C++ APIを提供:短所'))
808
+
809
+ Omit\n
810
+ (('note:省略'))
811
+
812
+ = Provide C++ API: ConsN\n(('note:C++ APIを提供:短所N'))
813
+
814
+ (('tag:center'))
815
+ Conv from Ruby may be a bother\n
816
+ (('note:Ruby実装の移植が面倒'))
817
+
818
+ * C++ with convenient Ruby C API needs more codes than Ruby\n
819
+ (('note:RubyのC APIにC++の便利APIがあってもRubyよりもたくさんコードが必要'))
820
+
821
+ = From Ruby: Rice\n(('note:RubyからRiceに移植'))
822
+
823
+ # coderay ruby
824
+ def fib(n)
825
+ prev = 1
826
+ current = 1
827
+ 1.step(n - 1).collect do
828
+ prev, current = current, current + prev
829
+ prev
830
+ end
831
+ end
832
+
833
+ = From Ruby: Rice\n(('note:RubyからRiceに移植'))
834
+
835
+ # coderay cpp
836
+ std::vector<uint64_t> fib(Rice::Object self, int n) {
837
+ uint64_t prev = 1, current = 1;
838
+ std::vector<uint64_t> numbers;
839
+ for (int i = 1; i < n; ++i) {
840
+ auto temp = current; current += prev; prev = temp;
841
+ numbers.push_back(prev);
842
+ }
843
+ return numbers;
844
+ }
Binary file
data/theme.rb ADDED
@@ -0,0 +1,4 @@
1
+ @title_slide_title_font_size = @large_font_size
2
+ @title_slide_subtitle_font_size = @small_font_size
3
+
4
+ include_theme("clear-code")
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rabbit-slide-kou-rubykaigi-2017
3
+ version: !ruby/object:Gem::Version
4
+ version: 2017.9.18.0
5
+ platform: ruby
6
+ authors:
7
+ - Kouhei Sutou
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-09-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rabbit
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: rabbit-theme-clear-code
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Ruby's extension API is for C. This talk proposes C++ as a better language
42
+ for extension API.
43
+ email:
44
+ - kou@clear-code.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".rabbit"
50
+ - README.rd
51
+ - Rakefile
52
+ - config.yaml
53
+ - extension-by-cpp.rab
54
+ - images/clear-code-silver-sponsor.png
55
+ - images/shocker.jpeg
56
+ - pdf/rubykaigi-2017-extension-by-cpp.pdf
57
+ - theme.rb
58
+ homepage: http://slide.rabbit-shocker.org/authors/kou/rubykaigi-2017/
59
+ licenses:
60
+ - CC-BY-SA-4.0
61
+ metadata: {}
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 2.5.2
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: 'Improve extension API: C++ as better language for extension'
82
+ test_files: []