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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 56f66d64ab2afa98268d83f3b952625f45affcf9
4
- data.tar.gz: c5b64688f7185fa0dd1a2504727f0f9f495d56a2
3
+ metadata.gz: 0c0abfd3a8ae726fe26d37775b62c519e25b2da2
4
+ data.tar.gz: 4fba2a4a8dc17fdeaf27763aef58a68b8bc9b2d8
5
5
  SHA512:
6
- metadata.gz: 0ff5431f5f138e4ef67318343aa4bbc17bd97187715ecc2f71b105defc96fe982b9a405b944d3428192fc6d41f3f38ad5e4b644b4aead1837c5e9eabc721a40a
7
- data.tar.gz: 6af279da5452f64a9ef449b9b500fd88e4983f582871a5d531f66ec0c38179e1c276e175a35ed2f659124af45b2952b5f4ebd1f898c9748187ac86a1b3b8c8ce
6
+ metadata.gz: fdd7427dae2390cf0057ac87c67a6f7fae9816beb3bfd92bb504defcedaa950545972ed08b4899c9e9acb0a22bd821d3772b68e68c696590b923a4817797b9bb
7
+ data.tar.gz: 73856de8025ee11d0b3572c2ded662f5649f15f86aa3fc7bbced1a7142edcbd0ace463ef5143f4bb68c8aba8e97ff483c82a7dc87ee44a55bc1a3c0f8973d3ae
@@ -7,10 +7,10 @@ tags:
7
7
  - extension
8
8
  - c++
9
9
  presentation_date: 2017-09-18
10
- version: 2017.9.18.0
10
+ version: 2017.9.18.1
11
11
  licenses:
12
12
  - CC-BY-SA-4.0
13
- slideshare_id:
13
+ slideshare_id: rubykaigi2017
14
14
  speaker_deck_id:
15
15
  ustream_id:
16
16
  vimeo_id:
@@ -82,7 +82,7 @@ Improve performance\n
82
82
  with C/C++ libraries\n
83
83
  (('note:C/C++のライブラリーを使った高速化'))
84
84
 
85
- * Not wanting to create binding\n
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 wanting to create binding\n
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:生のC API'))
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
- = Convenient API and C++\n(('note:便利なAPIとC++'))
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) { // lambda {|| "Hello"} in Ruby
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
- # Real benchmark code is in C++.
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
- # Real benchmark code is in C++.
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, 0.005675s, 0.005625s
496
- Lazy, 0.001142s, 0.005674s
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'))
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.0
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-02 00:00:00.000000000 Z
11
+ date: 2017-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rabbit