rabbit-slide-kou-rubykaigi-2017 2017.9.18.0 → 2017.9.18.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config.yaml +2 -2
- data/extension-by-cpp.rab +282 -48
- data/pdf/rubykaigi-2017-extension-by-cpp.pdf +0 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c0abfd3a8ae726fe26d37775b62c519e25b2da2
|
4
|
+
data.tar.gz: 4fba2a4a8dc17fdeaf27763aef58a68b8bc9b2d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fdd7427dae2390cf0057ac87c67a6f7fae9816beb3bfd92bb504defcedaa950545972ed08b4899c9e9acb0a22bd821d3772b68e68c696590b923a4817797b9bb
|
7
|
+
data.tar.gz: 73856de8025ee11d0b3572c2ded662f5649f15f86aa3fc7bbced1a7142edcbd0ace463ef5143f4bb68c8aba8e97ff483c82a7dc87ee44a55bc1a3c0f8973d3ae
|
data/config.yaml
CHANGED
data/extension-by-cpp.rab
CHANGED
@@ -82,7 +82,7 @@ Improve performance\n
|
|
82
82
|
with C/C++ libraries\n
|
83
83
|
(('note:C/C++のライブラリーを使った高速化'))
|
84
84
|
|
85
|
-
* Not
|
85
|
+
* Not want to create binding\n
|
86
86
|
(('note:バインディングを作りたいわけじゃない'))
|
87
87
|
|
88
88
|
= Point of improve perf\n(('note:高速化するために大事なこと'))
|
@@ -107,6 +107,17 @@ as much as possible\n
|
|
107
107
|
# 50x faster(50倍速い)
|
108
108
|
numbers.sum
|
109
109
|
|
110
|
+
= FYI: #inject(symbol)\n(('note:参考情報:#inject(symbol)'))
|
111
|
+
|
112
|
+
# coderay ruby
|
113
|
+
|
114
|
+
numbers = (1..100000).to_a
|
115
|
+
# Move between C and Ruby: 25.1ms
|
116
|
+
numbers.inject(&:+)
|
117
|
+
# Done in C: 0.5ms
|
118
|
+
# 50x faster(50倍速い)
|
119
|
+
numbers.inject(:+)
|
120
|
+
|
110
121
|
= Extension and binding\n(('note:バインディングと拡張ライブラリー'))
|
111
122
|
|
112
123
|
* Extension(('note:(拡張ライブラリー)'))
|
@@ -169,7 +180,7 @@ Improve performance\n
|
|
169
180
|
with C/C++ libraries\n
|
170
181
|
(('note:C/C++のライブラリーを使った高速化'))
|
171
182
|
|
172
|
-
* Not
|
183
|
+
* Not want to create binding\n
|
173
184
|
(('note:バインディングを作りたいわけじゃない'))
|
174
185
|
|
175
186
|
= Use case\n(('note:高速化したい場面'))
|
@@ -179,7 +190,7 @@ with C/C++ libraries\n
|
|
179
190
|
* Combine array/matrix operations\n
|
180
191
|
(('note:配列・行列に対する演算をまとめる'))
|
181
192
|
|
182
|
-
= Raw C API\n(('note
|
193
|
+
= Raw C API for extension\n(('note:拡張ライブラリー用の生のC API'))
|
183
194
|
|
184
195
|
(('tag:center'))
|
185
196
|
Not bad but has some verbosities because of C\n
|
@@ -222,14 +233,55 @@ Not bad but has some verbosities because of C\n
|
|
222
233
|
* Boost.Python: ((*C++*)) + Python
|
223
234
|
* pybind11: ((*C++*))11 + Python
|
224
235
|
|
225
|
-
=
|
236
|
+
= Useful C++ properties\n(('note:C++の便利の性質'))
|
226
237
|
|
227
238
|
* C++ can use C API directory\n
|
228
239
|
(('note:C++ではCのAPIを直接使える'))
|
229
240
|
* No need wrapper API nor libffi\n
|
230
241
|
(('note:ラッパーAPIもlibffiもいらない'))
|
231
|
-
* C++ has many convenient features\n
|
232
|
-
(('note:C
|
242
|
+
* C++((*11 or later*)) has many convenient features\n
|
243
|
+
(('note:C++11以降には便利機能がたくさんある'))
|
244
|
+
|
245
|
+
= C++ convenient feature1\n(('note:C++の便利機能1'))
|
246
|
+
|
247
|
+
(('tag:center'))
|
248
|
+
Type detection by auto (C++11)\n
|
249
|
+
(('note:autoで型推論'))
|
250
|
+
|
251
|
+
# coderay cpp
|
252
|
+
|
253
|
+
int n = 10;
|
254
|
+
auto square = n * n;
|
255
|
+
// square's type is "int"
|
256
|
+
// squareの型は「int」
|
257
|
+
|
258
|
+
= C++ convenient feature2\n(('note:C++の便利機能2'))
|
259
|
+
|
260
|
+
(('tag:center'))
|
261
|
+
Lambda expression (C++11)\n
|
262
|
+
(('note:(ラムダ式)'))
|
263
|
+
|
264
|
+
# coderay cpp
|
265
|
+
|
266
|
+
// In Ruby: ->(n) {n * n}
|
267
|
+
auto square = [](int n) {
|
268
|
+
return n * n; // Return type is detected
|
269
|
+
};
|
270
|
+
square(10); // => 100
|
271
|
+
|
272
|
+
= C++ convenient feature3\n(('note:C++の便利機能3'))
|
273
|
+
|
274
|
+
(('tag:center'))
|
275
|
+
Default argument\n
|
276
|
+
(('note:(デフォルト引数)'))
|
277
|
+
|
278
|
+
# coderay cpp
|
279
|
+
|
280
|
+
// In Ruby: def square(n=10)
|
281
|
+
int square(int n=10) {
|
282
|
+
return n * n;
|
283
|
+
}
|
284
|
+
// square() == square(10)
|
233
285
|
|
234
286
|
= Convenient API example1\n(('note:便利なAPI例1'))
|
235
287
|
|
@@ -260,9 +312,10 @@ Not bad but has some verbosities because of C\n
|
|
260
312
|
// C++: Ext++
|
261
313
|
#include <ruby.hpp>
|
262
314
|
extern "C" void Init_sample(void) {
|
315
|
+
// Parent class (rb_cObject) is omittable
|
263
316
|
rb::Class("Sample"). // class Sample in Ruby
|
264
317
|
define_method("hello", // def hello in Ruby
|
265
|
-
[](VALUE self) { //
|
318
|
+
[](VALUE self) { // ->() {"Hello"} in Ruby
|
266
319
|
return rb_str_new_static("Hello");
|
267
320
|
});
|
268
321
|
}
|
@@ -275,16 +328,227 @@ Not bad but has some verbosities because of C\n
|
|
275
328
|
#include <ruby.h>
|
276
329
|
static VALUE rb_sample_hello(VALUE self) {
|
277
330
|
return rb_str_new_static("Hello");
|
278
|
-
}
|
331
|
+
} /* ↑Definition. */
|
279
332
|
void Init_sample(void) {
|
333
|
+
/* ↓Must specify parent class. */
|
280
334
|
VALUE sample = rb_define_class("Sample", rb_cObject);
|
335
|
+
/* ↓Registration. They are separated. */
|
281
336
|
rb_define_method(sample, "hello", rb_sample_hello, 0);
|
282
337
|
}
|
283
338
|
|
339
|
+
= C++ convenient feature4\n(('note:C++の便利機能4'))
|
340
|
+
|
341
|
+
(('tag:center'))
|
342
|
+
Custom type conversion\n
|
343
|
+
(('note:(型変換のカスタマイズ)'))
|
344
|
+
|
345
|
+
* "Cast" is customizable\n
|
346
|
+
(('note:「キャスト」をカスタマイズできるということ'))
|
347
|
+
|
348
|
+
= Custom type conversion\n(('note:(型変換のカスタマイズ)'))
|
349
|
+
|
350
|
+
# coderay cpp
|
351
|
+
|
352
|
+
// Wrapper class of VALUE
|
353
|
+
class Object {
|
354
|
+
public:
|
355
|
+
// def initialize(rb_object)
|
356
|
+
// @rb_object_ = rb_object
|
357
|
+
// end
|
358
|
+
Object(VALUE rb_object) : rb_object_(rb_object) {}
|
359
|
+
private:
|
360
|
+
VALUE rb_object_;
|
361
|
+
};
|
362
|
+
|
363
|
+
= Custom type conversion\n(('note:(型変換のカスタマイズ)'))
|
364
|
+
|
365
|
+
# coderay cpp
|
366
|
+
|
367
|
+
class Object {
|
368
|
+
operator bool() const {
|
369
|
+
return RTEST(rb_object_);
|
370
|
+
}
|
371
|
+
};
|
372
|
+
// Object nil(Qnil); // Qnil wrapper
|
373
|
+
// if (nil) { → if (RTEST(Qnil)) {
|
374
|
+
|
375
|
+
= Custom type conversion\n(('note:(型変換のカスタマイズ)'))
|
376
|
+
|
377
|
+
# coderay cpp
|
378
|
+
|
379
|
+
// Trap1(罠1)
|
380
|
+
// bool→int cast is available
|
381
|
+
// Implicit Object→bool→ int cast
|
382
|
+
// bool→intのキャストができるので
|
383
|
+
// 暗黙的にObject→bool→intとキャスト
|
384
|
+
Object(Qture) + 1; // → RTEST(Qtrue) + 1
|
385
|
+
// → 1 + 1
|
386
|
+
// → 2
|
387
|
+
|
388
|
+
= Custom type conversion\n(('note:(型変換のカスタマイズ)'))
|
389
|
+
|
390
|
+
# coderay cpp
|
391
|
+
|
392
|
+
class Object {
|
393
|
+
// Deny explicit cast (C++11)
|
394
|
+
// 暗黙のキャストを禁止(C++11)
|
395
|
+
explicit operator bool() const {
|
396
|
+
return RTEST(rb_object_);
|
397
|
+
}
|
398
|
+
};
|
399
|
+
// Object(Qtrue) + 1; // → Compile error
|
400
|
+
|
401
|
+
= Custom type conversion\n(('note:(型変換のカスタマイズ)'))
|
402
|
+
|
403
|
+
# coderay cpp
|
404
|
+
|
405
|
+
// Trap2(罠2)
|
406
|
+
class Object {
|
407
|
+
public:
|
408
|
+
// Used as implicit VALUE→Object cast
|
409
|
+
// 暗黙のVALUE→Objectキャストに使われる
|
410
|
+
Object(VALUE rb_object);
|
411
|
+
};
|
412
|
+
|
413
|
+
= Custom type conversion\n(('note:(型変換のカスタマイズ)'))
|
414
|
+
|
415
|
+
# coderay cpp
|
416
|
+
|
417
|
+
// Trap2(罠2)
|
418
|
+
// VALUE is just a number(VALUEはただの数値)
|
419
|
+
typedef unsigned long VALUE;
|
420
|
+
Object identify(Object x) {return x;}
|
421
|
+
// Implicit VALUE→Object cast
|
422
|
+
// 暗黙的にVALUE→Objectとキャスト
|
423
|
+
identify(100); // == identify(Object(100));
|
424
|
+
|
425
|
+
= Custom type conversion\n(('note:(型変換のカスタマイズ)'))
|
426
|
+
|
427
|
+
# coderay cpp
|
428
|
+
|
429
|
+
class Object {
|
430
|
+
// Deny explicit cast
|
431
|
+
// 暗黙のキャストを禁止
|
432
|
+
explicit Object(VALUE rb_object);
|
433
|
+
};
|
434
|
+
// identify(100); // → Compile error
|
435
|
+
|
436
|
+
= Custom type conversion\n(('note:(型変換のカスタマイズ)'))
|
437
|
+
|
438
|
+
# coderay cpp
|
439
|
+
|
440
|
+
class Object {
|
441
|
+
operator VALUE() const {return rb_object_;}
|
442
|
+
};
|
443
|
+
// Convenient(便利)
|
444
|
+
rb_p(Object(Qnil)); // → rb_p(Qnil);
|
445
|
+
// Not compile error. Hmm...
|
446
|
+
Object(Qnil) + 1; // → Qnil + 1;
|
447
|
+
// → 8 + 1;
|
448
|
+
// → 9;
|
449
|
+
|
450
|
+
= C++ convenient feature6\n(('note:C++の便利機能6'))
|
451
|
+
|
452
|
+
(('tag:center'))
|
453
|
+
Template and specialization\n
|
454
|
+
(('note:(テンプレートと特殊化)'))
|
455
|
+
|
456
|
+
* Usable for consistent cast API\n
|
457
|
+
(('note:一貫性のあるキャストAPIに使える'))
|
458
|
+
|
459
|
+
= Consistent cast API\n(('note:一貫性のあるキャストAPI'))
|
460
|
+
|
461
|
+
# coderay cpp
|
462
|
+
|
463
|
+
namespace rb {
|
464
|
+
// Consistent cast API
|
465
|
+
// Example: rb::cast<int32_t>(Object(NUM2INT(10));
|
466
|
+
// Example: rb::cast<Object>(10);
|
467
|
+
// FYI: C++ cast syntax: static_cast<TYPE>(expression)
|
468
|
+
template <typename RETURN_TYPE,
|
469
|
+
typename ARGUMENT_TYPE>
|
470
|
+
inline RETURN_TYPE cast(ARGUMENT_TYPE object);
|
471
|
+
}
|
472
|
+
|
473
|
+
= Consistent cast API\n(('note:一貫性のあるキャストAPI'))
|
474
|
+
|
475
|
+
# coderay cpp
|
476
|
+
|
477
|
+
template <> // rb::cast<int32_t>(Object(NUM2INT(10));
|
478
|
+
inline int32_t cast<int32_t, Object>(Object rb_object) {
|
479
|
+
return NUM2INT(rb_object);
|
480
|
+
}
|
481
|
+
template <> // rb::cast<Object>(10);
|
482
|
+
inline Object cast<Object, int32_t>(int32_t n) {
|
483
|
+
return Object(INT2NUM(n));
|
484
|
+
}
|
485
|
+
|
486
|
+
= Consistent cast API\n(('note:一貫性のあるキャストAPI'))
|
487
|
+
|
488
|
+
# coderay cpp
|
489
|
+
|
490
|
+
// rb::cast<const char *>(Object(rb_str_new_cstr("X"));
|
491
|
+
template <> inline
|
492
|
+
const char *cast<const char *, Object>(Object rb_object) {
|
493
|
+
VALUE rb_object_raw = rb_object;
|
494
|
+
return StringValueCStr(rb_object_raw);
|
495
|
+
}
|
496
|
+
template <> inline // rb::cast<Object>("hello");
|
497
|
+
Object cast<Object, const char *>(const char *c_string) {
|
498
|
+
return Object(rb_str_new_cstr(c_string));
|
499
|
+
}
|
500
|
+
|
501
|
+
= C++ convenient feature5\n(('note:C++の便利機能5'))
|
502
|
+
|
503
|
+
(('tag:center'))
|
504
|
+
Initializer list (C++11)\n
|
505
|
+
(('note:初期化リスト(C++11)'))
|
506
|
+
|
507
|
+
* "{A, B, C, ...}" is customizable\n
|
508
|
+
(('note:「{A, B, C, ...}」をカスタマイズできる'))
|
509
|
+
|
510
|
+
= Initializer list\n(('note:初期化リスト'))
|
511
|
+
|
512
|
+
# coderay cpp
|
513
|
+
|
514
|
+
Object Object::send(
|
515
|
+
ID name_id, std::initializer_list<VALUE> args);
|
516
|
+
// Ruby: "hello".send(:tr, "e", "E")
|
517
|
+
Object(rb_str_new_cstr("hello")).
|
518
|
+
send(rb_intern("tr"),
|
519
|
+
{rb_str_new_cstr("e"),
|
520
|
+
rb_str_new_cstr("E")});
|
521
|
+
|
522
|
+
= Initializer list\n(('note:初期化リスト'))
|
523
|
+
|
524
|
+
# coderay cpp
|
525
|
+
|
526
|
+
Object Object::send(
|
527
|
+
ID name_id,
|
528
|
+
std::initializer_list<VALUE> args,
|
529
|
+
VALUE (*block)(VALUE data));
|
530
|
+
// Ruby: array.send(:collect) {true}
|
531
|
+
Object(array).
|
532
|
+
send(rb_intern("collect"),
|
533
|
+
{}, // Clear API than variable arguments
|
534
|
+
[](VALUE data) {return Qtrue;});
|
535
|
+
|
284
536
|
= Convenient API example2\n(('note:便利なAPI例2'))
|
285
537
|
|
286
538
|
# coderay cpp
|
287
539
|
|
540
|
+
// C++: Ext++
|
541
|
+
rb::Object(rb_n).
|
542
|
+
send("step",
|
543
|
+
// Implicit Object→VALUE cast
|
544
|
+
{rb::cast<rb::Object>(10)},
|
545
|
+
[](VALUE i) {return rb_p(i)});
|
546
|
+
// n.step(10) {|i| p i}
|
547
|
+
|
548
|
+
= Convenient API example3\n(('note:便利なAPI例3'))
|
549
|
+
|
550
|
+
# coderay cpp
|
551
|
+
|
288
552
|
// C++: Rice
|
289
553
|
#include <rice/Class.hpp>
|
290
554
|
static const char * // Not VALUE! (Auto convert)
|
@@ -296,41 +560,6 @@ Not bad but has some verbosities because of C\n
|
|
296
560
|
define_method("hello", &rb_sample_hello);
|
297
561
|
}
|
298
562
|
|
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
563
|
= C++ based API: Pros1\n(('note:C++ベースのAPI:長所1'))
|
335
564
|
|
336
565
|
(('tag:center'))
|
@@ -398,7 +627,7 @@ Easy to optimize\n
|
|
398
627
|
|
399
628
|
# coderay cpp
|
400
629
|
|
401
|
-
// Rice
|
630
|
+
// C++: Rice
|
402
631
|
cHello.
|
403
632
|
define_method(
|
404
633
|
"hello",
|
@@ -465,7 +694,7 @@ Easy to optimize\n
|
|
465
694
|
# coderay ruby
|
466
695
|
|
467
696
|
# Define only benchmark code in Ruby.
|
468
|
-
#
|
697
|
+
# Benchmark target code is in C++.
|
469
698
|
n = 10000
|
470
699
|
Bench = Class.new do
|
471
700
|
n.times do |i|
|
@@ -479,7 +708,7 @@ Easy to optimize\n
|
|
479
708
|
# coderay ruby
|
480
709
|
|
481
710
|
# Call benchmark code in Ruby.
|
482
|
-
#
|
711
|
+
# Benchmark target code is in C++.
|
483
712
|
n = 10000
|
484
713
|
bench = Bench.new
|
485
714
|
n.times do |i|
|
@@ -492,8 +721,8 @@ Easy to optimize\n
|
|
492
721
|
|
493
722
|
Type, Define only, Called
|
494
723
|
|
495
|
-
Normal,
|
496
|
-
Lazy,
|
724
|
+
Normal, 5ms, 5ms
|
725
|
+
Lazy, 1ms, 5ms
|
497
726
|
|
498
727
|
(('tag:center'))
|
499
728
|
5x faster when any methods aren't called\n
|
@@ -548,6 +777,11 @@ Exception\n
|
|
548
777
|
* For optimizing w/ easy to use API\n
|
549
778
|
(('note:例:使いやすいAPIを維持したまま最適化するとき'))
|
550
779
|
|
780
|
+
== Slide properties
|
781
|
+
|
782
|
+
: image-slide-number-last-slide
|
783
|
+
true
|
784
|
+
|
551
785
|
= Appendix\n(('note:付録'))
|
552
786
|
|
553
787
|
(('tag:center'))
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rabbit-slide-kou-rubykaigi-2017
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2017.9.18.
|
4
|
+
version: 2017.9.18.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kouhei Sutou
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rabbit
|