write your c extension for ruby
play

Write Your C Extension for Ruby (Jian Weihang) @tonytonyjan - PowerPoint PPT Presentation

Write Your C Extension for Ruby (Jian Weihang) @tonytonyjan Bonjour Jian, Weihang tonytonyjan.net tonytonyjan tonytonyjan tonytonyjan tonytonyjan tonytonyjan tonytonyjan Double Keyboard Player Ruby Postgraduate


  1. Write Your C Extension for Ruby 簡煒航 (Jian Weihang) @tonytonyjan

  2. Bonjour

  3. 簡煒航 Jian, Weihang

  4. tonytonyjan.net

  5. tonytonyjan

  6. tonytonyjan

  7. tonytonyjan

  8. tonytonyjan

  9. tonytonyjan

  10. tonytonyjan

  11. Double Keyboard Player

  12. Ruby

  13. Postgraduate

  14. Freelancer

  15. Book Writer

  16. Coach of Rails Girls Taipei

  17. Startup brainana.com 5xruby.tw

  18. Taiwan

  19. 臺灣( Taiwan )

  20. 臺灣( Taiwan )

  21. 2015-02-18 Montreal Taipei -18°C 19°C

  22. Happy Chinese New Year It’s Year of the RAM Ram

  23. Write Your C Extension for Ruby 簡煒航 (Jian Weihang) @tonytonyjan

  24. Overview • Compilation • File Structure • Basic MRI API • Pointer Wrapper

  25. Why C Extension?

  26. Beast from “Kung Fu Hustle”

  27. “What a fast code!”

  28. “You code fast!”

  29. Code Performance vs Development Efficiency

  30. ASM C C++ Performance C Extension Perl Ruby Python Development

  31. First step?

  32. Profiling Tool gem install ruby-prof

  33. Jaro-winkler Distance Pure Ruby Implementation 1.6918 ms

  34. Replace with C Extension 0.5103 ms

  35. Ruby EXIF Readers • mini_exiftool - CLI wrapper of Exiftool • exifr - Pure Ruby • exif - C Extension of libexif

  36. GitHub tonytonyjan/jaro_winkler tonytonyjan/exif

  37. Make C Extension

  38. Solutions • C API of Ruby • rubyinline - mixing C code into Ruby • SWIG - Simplified Wrapper and Interface Generator

  39. rubyinline

  40. SWIG 1 function 1 declaration foo.c foo.h libfoo.i $ swig -ruby libfoo.i foo.c foo.h libfoo_wrap.c 2k lines clang/gcc libfoo.so 3x bigger than MRI C API implementation

  41. SWIG is similar to C, but not C

  42. MRI API is just Fine

  43. What happen in “require” It will load “foo.rb” foo.so, foo.o and foo.bundle RbConfig::CONFIG['DLEXT']

  44. To write a loadable Ruby module is easy.

  45. What about write a native loadable module?

  46. Entry of a C Program

  47. Entry of C Extension

  48. Compilation

  49. How to compile? • Compile in-line • autoconf/pkg-config • MakeMakefile (recommended)

  50. Compile in-line

  51. pkg-config

  52. mkmf (Make Makefile) $ ruby extconf.rb $ make

  53. installation path

  54. custom source path $ ruby extconf.rb $ make

  55. Conditional Processing

  56. Conditional Processing AutoConfig - Generic Header Checks

  57. Conditional Processing mkmf methods Compilor Optoins have_header(“foo”) -DHAVE_FOO_H have_library(“foo”) -lexif have_type(“foo”) -DHAVE_TYPE_FOO have_var(“foo”) -DHAVE_FOO have_struct_member('struct foo', 'bar') -DHAVE_STRUCT_FOO_BAR have_func(“foo”) -DHAVE_FOO

  58. It’s just DSL

  59. Configurable Target Path

  60. dir_config

  61. Setup Gemspec

  62. That’s it

  63. Yon’t need autotools, mkmf gives you the best.

  64. File Structure

  65. Typical File Structure mysql2, nokogiri, sqlite3

  66. It’s ambiguous!

  67. Better File Structure pg, bcrypt, eventmachine

  68. Development Workflow

  69. `gem install` will generate Makefile & build automatically.

  70. While developing… $ cd ext/ $ ruby extconf.rb $ make $ cd .. $ ruby -I ext -r foo_ext -e ‘…’ It’s too tedious.

  71. Life can be easier.

  72. gem install rake-compiler

  73. $ rake -D

  74. Using rake-compiler $ rake compile test

  75. rake-compiler is for development.

  76. It’s nothing to do with gem installation.

  77. Basic C API

  78. Key Knowledge • Ruby is OO, C is not. • C variables have types but data don’t. • Ruby variables have no types but data do. • Data in Ruby are represented by C type “VALUE”, and “VALUE” data has its own data-type.

  79. Define Module/Class Ruby C

  80. Nested Class/Module Ruby C

  81. Define Method Ruby function pointer C argc

  82. self Convert Ruby String to C String Singleton Instance of rb_cNilClass (there are also Qfalse, Qtrue) self

  83. Ruby data <-> C data Fixnum Numeric String FIX2INT(value) NUM2INT(value) int INT2FIX(i) INT2NUM(l) FIX2LONG(value) NUM2LONG(value) long LONG2FIX(l) LONG2NUM(l) NUM2DBL(value) double rb_float_new(f) StringValueCStr(value) char* rb_str_new_cstr(s)

  84. Steps of implementation

  85. Type Checking

  86. Ruby C

  87. internal VALUE Types T_NIL T_STRING T_STRUCT T_FILE T_OBJECT T_REGEXP T_BIGNUM T_TRUE T_CLASS T_ARRAY T_FIXNUM T_FALSE T_MODULE T_HASH T_COMPLEX T_DATA T_FLOAT T_SYMBOL T_RATIONAL

  88. Pointer Wrapper

  89. C is not OOP

  90. However, there is structure in C.

  91. User instance u1 = User.new(…) Wrapped C Struct new() char name[20] char desc[20] hello() User instance u2 = User.new(…) Wrapped C Struct new() char name[20] hello() char desc[20]

  92. User#new(name, desc) Ruby class C struct return mark function pointer ActiveRecord::Persistence#destroy free function pointer

  93. User#hello return Ruby instance C struct

  94. What about C++?

  95. That’s it!

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend