SlideShare una empresa de Scribd logo
1 de 20
Descargar para leer sin conexión
Rubyの拡張を
Crystalで書いてみる
Writing Ruby extension with Crystal
Hirofumi Wakasugi (@5t111111)
Native Extension
Fetching: nokogiri-1.6.7.1.gem (100%)
Building native extensions. This could take a while...
• 特に実行速度が重要な処理をCで書くことができる
• 既存のCライブラリを利用することができる
RubyはC言語で拡張ライブラリを書くことができる
Crystal C Library Bindings
lib LibC
fun pow(x: Float64, y: Float64) : Float64
fun sqrt(val: Float64) : Float64
end
puts(LibC.pow(10, 10))
puts(LibC.sqrt(4))
end
CrystalでCのバインディングを書くのはとても簡単
うん、それなら
CrystalでRubyの拡張書けそう!
def fibonacci(n)
return n if n <= 1
fibonacci(n - 1) + fibonacci(n - 2)
end
まず、この単純なフィボナッチ数列の関数を
Ruby拡張ライブラリとしてCrystalで書きます
Example 1
lib LibRuby
type VALUE = Void*
$rb_cObject : VALUE
fun rb_define_global_function(name : UInt8*, func : VALUE, VALUE -> VALUE, argc : Int32)
fun rb_num2int(value : VALUE) : Int32
fun rb_int2inum(value : Int32) : VALUE
end
def fibonacci_cr(self : LibRuby::VALUE, value : LibRuby::VALUE)
int_value = LibRuby.rb_num2int(value)
LibRuby.rb_int2inum(fibonacci_cr2(int_value))
end
def fibonacci_cr2(n)
return n if n <= 1
fibonacci_cr2(n - 1) + fibonacci_cr2(n - 2)
end
fun init = Init_extension_with_crystal
GC.init
LibCrystalMain.__crystal_main(0, Pointer(Pointer(UInt8)).null)
LibRuby.rb_define_global_function("fibonacci_cr", ->fibonacci_cr, 1);
end
Example 1 - fibobacci_cr
user system total real
fibonacci (ruby) 16.760000 0.040000 16.800000 ( 16.963310)
fibonacci (crystal) 0.830000 0.010000 0.840000 ( 0.827128)
うん、速い
Example 1
class Takeuchi
def self.tarai(x, y, z)
if y < x
tarai(
tarai(x - 1, y, z),
tarai(y - 1, z, x),
tarai(z - 1, x, y)
)
else
y
end
end
end
たらい回し関数も書いてみます
Example 2
lib LibRuby
type VALUE = Void*
$rb_cObject : VALUE
fun rb_define_class(name : UInt8*, super : VALUE) : VALUE
fun rb_define_module_function(klass : VALUE, name : UInt8*, func : VALUE, VALUE, VALUE, VALUE -> VALUE, argc : Int32)
fun rb_num2int(value : VALUE) : Int32
fun rb_int2inum(value : Int32) : VALUE
end
def tarai(self : LibRuby::VALUE, x : LibRuby::VALUE, y : LibRuby::VALUE, z : LibRuby::VALUE)
int_x = LibRuby.rb_num2int(x)
int_y = LibRuby.rb_num2int(y)
int_z = LibRuby.rb_num2int(z)
LibRuby.rb_int2inum(tarai2(int_x, int_y, int_z))
end
def tarai2(x, y, z)
if y < x
tarai2(
tarai2(x - 1, y, z),
tarai2(y - 1, z, x),
tarai2(z - 1, x, y)
)
else
y
end
end
fun init = Init_extension_with_crystal
GC.init
LibCrystalMain.__crystal_main(0, Pointer(Pointer(UInt8)).null)
rb_class_takeuchi = LibRuby.rb_define_class("TakeuchiCr", LibRuby.rb_cObject)
LibRuby.rb_define_module_function(rb_class_takeuchi, "tarai", ->tarai, 3);
end
Example 2 - TakeuchiCr.tarai
user system total real
tarai (ruby) 19.810000 0.050000 19.860000 ( 20.248620)
tarai (crystal) 0.970000 0.000000 0.970000 ( 0.998764)
うん、速い
Example 2
さあ、つらいのはここから
Tsurami 1
person = LibRuby.rb_define_class("Person", LibRuby.rb_cObject)
LibRuby.rb_define_method(person, "Hello", ->hello, 1);
• Crystalの表現力を活用することが難しい
• 規模が大きくなってくるとかなり見通しが悪くなる
結局、普通に使うとC APIのバインディングでしかない
Tsurami 2
#define RB_FIX2LONG(x) ((long)RSHIFT((SIGNED_VALUE)(x),1))
#define StringValuePtr(v) rb_string_value_ptr(&(v))
• Cから扱わない場合シンボルを宣言するのが大変
• 毎回「ruby.h」とかをがんばって読むことになる
Ruby C APIではマクロが多用される
Tsurami 3
fun rb_define_method(klass : VALUE,
name : UInt8*,
func : VALUE, VALUE -> VALUE,
argc : Int32)
• 関数の型を指定する必要がある
• これ以外の型の関数を渡すとコンパイルエラー
Ruby C API関数の引数が関数ポインタのとき…
crystal_ruby
Write Ruby extensions in Crystal.
https://github.com/manastech/crystal_ruby
• 公式による「Proof of Concept」
• 意識高い
• 最新のCrystalでは動かすのにちょっと修正が要る
Proof of Concept (PoC)
ruby_extension "test_ruby",
class Foo
def foo(a)
"From Crystal!! #{a}"
end
end
ruby_extensionマクロでコード(文字列)を処理
マクロに渡されたコードはParserでパースされる
Proof of Concept (PoC)
class MyVisitor < Visitor
…
def visit(node : ClassDef)
@str << %(_class = Ruby::Class.new "#{node.name}"n)
end
def visit(node : Def)
@str << %(_class.def "#{node.name}", #{node.args.size}, )
@str << %[->(self : LibRuby::VALUE, ]
node.args.each do |arg|
@str << %(_#{arg.name} : LibRuby::VALUE, )
…
end
…
end
ASTノードはVisitorを継承したクラスで処理される
関数ポインタは型をVoid*で定義しておいて、ここで具体的な型として設定される
まともに動かないけど意識高いPoC <3
Matome
• Rubyの拡張をCrystalで書ける、が普通に書くとつらい
• でも、Crystalで拡張を書く利点は大きい
‣ やっぱり速い
‣ Rubyのシンタックスと非常に近い
• 公式がRubyの拡張に対して積極的
御静聴
有難う御座いました
本スライド中のサンプルコード
およびその出力内容は
すべて Crystal 0.10.2 で確認しています
LIVE FOREVER

Más contenido relacionado

La actualidad más candente

Rubyのソースコードを読んでみよう(入門編)
Rubyのソースコードを読んでみよう(入門編)Rubyのソースコードを読んでみよう(入門編)
Rubyのソースコードを読んでみよう(入門編)baban ba-n
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門伸男 伊藤
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由kikairoya
 
C++ lecture-0
C++ lecture-0C++ lecture-0
C++ lecture-0sunaemon
 
(define)なしで再帰関数を定義する
(define)なしで再帰関数を定義する(define)なしで再帰関数を定義する
(define)なしで再帰関数を定義するblackenedgold
 
From Java To Clojure
From Java To ClojureFrom Java To Clojure
From Java To ClojureKent Ohashi
 
現実世界のJRuby(ショートバージョン)
現実世界のJRuby(ショートバージョン)現実世界のJRuby(ショートバージョン)
現実世界のJRuby(ショートバージョン)Hiroshi Nakamura
 
はてなブックマークにおけるアクセス制御 - 半環構造に基づくモデル化
はてなブックマークにおけるアクセス制御 - 半環構造に基づくモデル化はてなブックマークにおけるアクセス制御 - 半環構造に基づくモデル化
はてなブックマークにおけるアクセス制御 - 半環構造に基づくモデル化Lintaro Ina
 
並行プログラミングと継続モナド
並行プログラミングと継続モナド並行プログラミングと継続モナド
並行プログラミングと継続モナドKousuke Ruichi
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11nekko1119
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターンMoriharu Ohzu
 
関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会Koichi Sakata
 
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarrayRyosuke839
 
Rubyの御先祖CLUのお話(原本)
Rubyの御先祖CLUのお話(原本)Rubyの御先祖CLUのお話(原本)
Rubyの御先祖CLUのお話(原本)洋史 東平
 
Spectacular Future with clojure.spec
Spectacular Future with clojure.specSpectacular Future with clojure.spec
Spectacular Future with clojure.specKent Ohashi
 

La actualidad más candente (20)

Rubyのソースコードを読んでみよう(入門編)
Rubyのソースコードを読んでみよう(入門編)Rubyのソースコードを読んでみよう(入門編)
Rubyのソースコードを読んでみよう(入門編)
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
 
C++ lecture-0
C++ lecture-0C++ lecture-0
C++ lecture-0
 
Emcpp item31
Emcpp item31Emcpp item31
Emcpp item31
 
(define)なしで再帰関数を定義する
(define)なしで再帰関数を定義する(define)なしで再帰関数を定義する
(define)なしで再帰関数を定義する
 
From Java To Clojure
From Java To ClojureFrom Java To Clojure
From Java To Clojure
 
現実世界のJRuby(ショートバージョン)
現実世界のJRuby(ショートバージョン)現実世界のJRuby(ショートバージョン)
現実世界のJRuby(ショートバージョン)
 
はてなブックマークにおけるアクセス制御 - 半環構造に基づくモデル化
はてなブックマークにおけるアクセス制御 - 半環構造に基づくモデル化はてなブックマークにおけるアクセス制御 - 半環構造に基づくモデル化
はてなブックマークにおけるアクセス制御 - 半環構造に基づくモデル化
 
並行プログラミングと継続モナド
並行プログラミングと継続モナド並行プログラミングと継続モナド
並行プログラミングと継続モナド
 
boost tour 1.48.0 all
boost tour 1.48.0 allboost tour 1.48.0 all
boost tour 1.48.0 all
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターン
 
関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会
 
C++14 Overview
C++14 OverviewC++14 Overview
C++14 Overview
 
Boost Tour 1.50.0 All
Boost Tour 1.50.0 AllBoost Tour 1.50.0 All
Boost Tour 1.50.0 All
 
不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray不遇の標準ライブラリ - valarray
不遇の標準ライブラリ - valarray
 
Rubyの御先祖CLUのお話(原本)
Rubyの御先祖CLUのお話(原本)Rubyの御先祖CLUのお話(原本)
Rubyの御先祖CLUのお話(原本)
 
Spectacular Future with clojure.spec
Spectacular Future with clojure.specSpectacular Future with clojure.spec
Spectacular Future with clojure.spec
 

Destacado

CrystalでもRailsを使いたいですか?
CrystalでもRailsを使いたいですか?CrystalでもRailsを使いたいですか?
CrystalでもRailsを使いたいですか?Masayuki Uchida
 
Crystal勉強会#4 LT資料
Crystal勉強会#4 LT資料 Crystal勉強会#4 LT資料
Crystal勉強会#4 LT資料 Taichiro Suzuki
 
静的型付け言語 Crystal
静的型付け言語 Crystal静的型付け言語 Crystal
静的型付け言語 Crystal5t111111
 
Opal - Ruby Style!! Ruby in the browser
Opal - Ruby Style!!  Ruby in the browserOpal - Ruby Style!!  Ruby in the browser
Opal - Ruby Style!! Ruby in the browserForrest Chang
 
Crystalを触り始めてから起こったこと
Crystalを触り始めてから起こったことCrystalを触り始めてから起こったこと
Crystalを触り始めてから起こったことat grandpa
 
Ruby 風シンタックスな静的言語 Crystal の紹介
Ruby 風シンタックスな静的言語 Crystal の紹介Ruby 風シンタックスな静的言語 Crystal の紹介
Ruby 風シンタックスな静的言語 Crystal の紹介Kazuki Matsushita
 
Crystal学習の際に印象に残った点
Crystal学習の際に印象に残った点Crystal学習の際に印象に残った点
Crystal学習の際に印象に残った点stefafafan
 
Crystal is a Rubyists friend (quick anecdote)
Crystal is a Rubyists friend (quick anecdote)Crystal is a Rubyists friend (quick anecdote)
Crystal is a Rubyists friend (quick anecdote)Forrest Chang
 
Crystal on cygwin (WIP)
Crystal on cygwin (WIP)Crystal on cygwin (WIP)
Crystal on cygwin (WIP)fd0
 
Building native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahBuilding native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahNick Plante
 
RubyConf Brazil 2010 - Mirah
RubyConf Brazil 2010 - MirahRubyConf Brazil 2010 - Mirah
RubyConf Brazil 2010 - MirahCharles Nutter
 
Elixirについて私が知ってる二、三の事柄
Elixirについて私が知ってる二、三の事柄Elixirについて私が知ってる二、三の事柄
Elixirについて私が知ってる二、三の事柄Tsunenori Oohara
 
Opal chapter 4_a_new_hope
Opal chapter 4_a_new_hopeOpal chapter 4_a_new_hope
Opal chapter 4_a_new_hopeForrest Chang
 
東京 Crystal 勉強会 #4 in 渋谷 - イントロダクション
東京 Crystal 勉強会 #4 in 渋谷 - イントロダクション東京 Crystal 勉強会 #4 in 渋谷 - イントロダクション
東京 Crystal 勉強会 #4 in 渋谷 - イントロダクションat grandpa
 
Reducing Boilerplate and Combining Effects: A Monad Transformer Example
Reducing Boilerplate and Combining Effects: A Monad Transformer ExampleReducing Boilerplate and Combining Effects: A Monad Transformer Example
Reducing Boilerplate and Combining Effects: A Monad Transformer ExampleConnie Chen
 
Make your programs Free
Make your programs FreeMake your programs Free
Make your programs FreePawel Szulc
 

Destacado (20)

How to write Ruby extensions with Crystal
How to write Ruby extensions with CrystalHow to write Ruby extensions with Crystal
How to write Ruby extensions with Crystal
 
CrystalでもRailsを使いたいですか?
CrystalでもRailsを使いたいですか?CrystalでもRailsを使いたいですか?
CrystalでもRailsを使いたいですか?
 
Crystal勉強会#4 LT資料
Crystal勉強会#4 LT資料 Crystal勉強会#4 LT資料
Crystal勉強会#4 LT資料
 
静的型付け言語 Crystal
静的型付け言語 Crystal静的型付け言語 Crystal
静的型付け言語 Crystal
 
Opal - Ruby Style!! Ruby in the browser
Opal - Ruby Style!!  Ruby in the browserOpal - Ruby Style!!  Ruby in the browser
Opal - Ruby Style!! Ruby in the browser
 
Crystalを触り始めてから起こったこと
Crystalを触り始めてから起こったことCrystalを触り始めてから起こったこと
Crystalを触り始めてから起こったこと
 
Ruby 風シンタックスな静的言語 Crystal の紹介
Ruby 風シンタックスな静的言語 Crystal の紹介Ruby 風シンタックスな静的言語 Crystal の紹介
Ruby 風シンタックスな静的言語 Crystal の紹介
 
Crystal学習の際に印象に残った点
Crystal学習の際に印象に残った点Crystal学習の際に印象に残った点
Crystal学習の際に印象に残った点
 
router-simple.cr
router-simple.crrouter-simple.cr
router-simple.cr
 
Crystal
CrystalCrystal
Crystal
 
Crystal is a Rubyists friend (quick anecdote)
Crystal is a Rubyists friend (quick anecdote)Crystal is a Rubyists friend (quick anecdote)
Crystal is a Rubyists friend (quick anecdote)
 
Crystal on cygwin (WIP)
Crystal on cygwin (WIP)Crystal on cygwin (WIP)
Crystal on cygwin (WIP)
 
Rejectkaigi 2010
Rejectkaigi 2010Rejectkaigi 2010
Rejectkaigi 2010
 
Building native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahBuilding native Android applications with Mirah and Pindah
Building native Android applications with Mirah and Pindah
 
RubyConf Brazil 2010 - Mirah
RubyConf Brazil 2010 - MirahRubyConf Brazil 2010 - Mirah
RubyConf Brazil 2010 - Mirah
 
Elixirについて私が知ってる二、三の事柄
Elixirについて私が知ってる二、三の事柄Elixirについて私が知ってる二、三の事柄
Elixirについて私が知ってる二、三の事柄
 
Opal chapter 4_a_new_hope
Opal chapter 4_a_new_hopeOpal chapter 4_a_new_hope
Opal chapter 4_a_new_hope
 
東京 Crystal 勉強会 #4 in 渋谷 - イントロダクション
東京 Crystal 勉強会 #4 in 渋谷 - イントロダクション東京 Crystal 勉強会 #4 in 渋谷 - イントロダクション
東京 Crystal 勉強会 #4 in 渋谷 - イントロダクション
 
Reducing Boilerplate and Combining Effects: A Monad Transformer Example
Reducing Boilerplate and Combining Effects: A Monad Transformer ExampleReducing Boilerplate and Combining Effects: A Monad Transformer Example
Reducing Boilerplate and Combining Effects: A Monad Transformer Example
 
Make your programs Free
Make your programs FreeMake your programs Free
Make your programs Free
 

Similar a Rubyの拡張をCrystalで書いてみる

イチからはじめるLuarida-マイコン
イチからはじめるLuarida-マイコンイチからはじめるLuarida-マイコン
イチからはじめるLuarida-マイコン三七男 山本
 
PythonでLispを実装した (evalつき)
PythonでLispを実装した (evalつき)PythonでLispを実装した (evalつき)
PythonでLispを実装した (evalつき)t-sin
 
Real World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたReal World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたblackenedgold
 
Introduction to cython
Introduction to cythonIntroduction to cython
Introduction to cythonAtsuo Ishimoto
 
Scalatronで楽しく学ぶ関数型プログラミング
Scalatronで楽しく学ぶ関数型プログラミングScalatronで楽しく学ぶ関数型プログラミング
Scalatronで楽しく学ぶ関数型プログラミングJun Saito
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたMITSUNARI Shigeo
 
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門Shiqiao Du
 
Common LispでGPGPU
Common LispでGPGPUCommon LispでGPGPU
Common LispでGPGPUgos-k
 
Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Ra Zon
 
Everyday Life with clojure.spec
Everyday Life with clojure.specEveryday Life with clojure.spec
Everyday Life with clojure.specKent Ohashi
 
Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelereaseShiqiao Du
 
“Design and Implementation of Generics for the .NET Common Language Runtime”他...
“Design and Implementation of Generics for the .NET Common Language Runtime”他...“Design and Implementation of Generics for the .NET Common Language Runtime”他...
“Design and Implementation of Generics for the .NET Common Language Runtime”他...Masahiro Sakai
 
Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Ra Zon
 
ROS Tutorial 02 - CIT
ROS Tutorial 02 - CITROS Tutorial 02 - CIT
ROS Tutorial 02 - CITDaiki Maekawa
 
Kobe.R #15 - Incanter チョットシッテル
Kobe.R #15 - Incanter チョットシッテルKobe.R #15 - Incanter チョットシッテル
Kobe.R #15 - Incanter チョットシッテルtnoda
 

Similar a Rubyの拡張をCrystalで書いてみる (20)

イチからはじめるLuarida-マイコン
イチからはじめるLuarida-マイコンイチからはじめるLuarida-マイコン
イチからはじめるLuarida-マイコン
 
PythonでLispを実装した (evalつき)
PythonでLispを実装した (evalつき)PythonでLispを実装した (evalつき)
PythonでLispを実装した (evalつき)
 
Real World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたReal World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみた
 
Prosym2012
Prosym2012Prosym2012
Prosym2012
 
たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
Introduction to cython
Introduction to cythonIntroduction to cython
Introduction to cython
 
Scalatronで楽しく学ぶ関数型プログラミング
Scalatronで楽しく学ぶ関数型プログラミングScalatronで楽しく学ぶ関数型プログラミング
Scalatronで楽しく学ぶ関数型プログラミング
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみた
 
Objc lambda
Objc lambdaObjc lambda
Objc lambda
 
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
 
Common LispでGPGPU
Common LispでGPGPUCommon LispでGPGPU
Common LispでGPGPU
 
Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]Scalaで萌える関数型プログラミング[1.1.RC1]
Scalaで萌える関数型プログラミング[1.1.RC1]
 
Everyday Life with clojure.spec
Everyday Life with clojure.specEveryday Life with clojure.spec
Everyday Life with clojure.spec
 
Cython intro prelerease
Cython intro prelereaseCython intro prelerease
Cython intro prelerease
 
“Design and Implementation of Generics for the .NET Common Language Runtime”他...
“Design and Implementation of Generics for the .NET Common Language Runtime”他...“Design and Implementation of Generics for the .NET Common Language Runtime”他...
“Design and Implementation of Generics for the .NET Common Language Runtime”他...
 
Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]Scalaで萌える関数型プログラミング[完全版]
Scalaで萌える関数型プログラミング[完全版]
 
Clojure
ClojureClojure
Clojure
 
C++11
C++11C++11
C++11
 
ROS Tutorial 02 - CIT
ROS Tutorial 02 - CITROS Tutorial 02 - CIT
ROS Tutorial 02 - CIT
 
Kobe.R #15 - Incanter チョットシッテル
Kobe.R #15 - Incanter チョットシッテルKobe.R #15 - Incanter チョットシッテル
Kobe.R #15 - Incanter チョットシッテル
 

Último

LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルCRI Japan, Inc.
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video UnderstandingToru Tamaki
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Gamesatsushi061452
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...Toru Tamaki
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイスCRI Japan, Inc.
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptxsn679259
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsWSO2
 

Último (10)

LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 

Rubyの拡張をCrystalで書いてみる

  • 1. Rubyの拡張を Crystalで書いてみる Writing Ruby extension with Crystal Hirofumi Wakasugi (@5t111111)
  • 2. Native Extension Fetching: nokogiri-1.6.7.1.gem (100%) Building native extensions. This could take a while... • 特に実行速度が重要な処理をCで書くことができる • 既存のCライブラリを利用することができる RubyはC言語で拡張ライブラリを書くことができる
  • 3. Crystal C Library Bindings lib LibC fun pow(x: Float64, y: Float64) : Float64 fun sqrt(val: Float64) : Float64 end puts(LibC.pow(10, 10)) puts(LibC.sqrt(4)) end CrystalでCのバインディングを書くのはとても簡単
  • 5. def fibonacci(n) return n if n <= 1 fibonacci(n - 1) + fibonacci(n - 2) end まず、この単純なフィボナッチ数列の関数を Ruby拡張ライブラリとしてCrystalで書きます Example 1
  • 6. lib LibRuby type VALUE = Void* $rb_cObject : VALUE fun rb_define_global_function(name : UInt8*, func : VALUE, VALUE -> VALUE, argc : Int32) fun rb_num2int(value : VALUE) : Int32 fun rb_int2inum(value : Int32) : VALUE end def fibonacci_cr(self : LibRuby::VALUE, value : LibRuby::VALUE) int_value = LibRuby.rb_num2int(value) LibRuby.rb_int2inum(fibonacci_cr2(int_value)) end def fibonacci_cr2(n) return n if n <= 1 fibonacci_cr2(n - 1) + fibonacci_cr2(n - 2) end fun init = Init_extension_with_crystal GC.init LibCrystalMain.__crystal_main(0, Pointer(Pointer(UInt8)).null) LibRuby.rb_define_global_function("fibonacci_cr", ->fibonacci_cr, 1); end Example 1 - fibobacci_cr
  • 7. user system total real fibonacci (ruby) 16.760000 0.040000 16.800000 ( 16.963310) fibonacci (crystal) 0.830000 0.010000 0.840000 ( 0.827128) うん、速い Example 1
  • 8. class Takeuchi def self.tarai(x, y, z) if y < x tarai( tarai(x - 1, y, z), tarai(y - 1, z, x), tarai(z - 1, x, y) ) else y end end end たらい回し関数も書いてみます Example 2
  • 9. lib LibRuby type VALUE = Void* $rb_cObject : VALUE fun rb_define_class(name : UInt8*, super : VALUE) : VALUE fun rb_define_module_function(klass : VALUE, name : UInt8*, func : VALUE, VALUE, VALUE, VALUE -> VALUE, argc : Int32) fun rb_num2int(value : VALUE) : Int32 fun rb_int2inum(value : Int32) : VALUE end def tarai(self : LibRuby::VALUE, x : LibRuby::VALUE, y : LibRuby::VALUE, z : LibRuby::VALUE) int_x = LibRuby.rb_num2int(x) int_y = LibRuby.rb_num2int(y) int_z = LibRuby.rb_num2int(z) LibRuby.rb_int2inum(tarai2(int_x, int_y, int_z)) end def tarai2(x, y, z) if y < x tarai2( tarai2(x - 1, y, z), tarai2(y - 1, z, x), tarai2(z - 1, x, y) ) else y end end fun init = Init_extension_with_crystal GC.init LibCrystalMain.__crystal_main(0, Pointer(Pointer(UInt8)).null) rb_class_takeuchi = LibRuby.rb_define_class("TakeuchiCr", LibRuby.rb_cObject) LibRuby.rb_define_module_function(rb_class_takeuchi, "tarai", ->tarai, 3); end Example 2 - TakeuchiCr.tarai
  • 10. user system total real tarai (ruby) 19.810000 0.050000 19.860000 ( 20.248620) tarai (crystal) 0.970000 0.000000 0.970000 ( 0.998764) うん、速い Example 2
  • 12. Tsurami 1 person = LibRuby.rb_define_class("Person", LibRuby.rb_cObject) LibRuby.rb_define_method(person, "Hello", ->hello, 1); • Crystalの表現力を活用することが難しい • 規模が大きくなってくるとかなり見通しが悪くなる 結局、普通に使うとC APIのバインディングでしかない
  • 13. Tsurami 2 #define RB_FIX2LONG(x) ((long)RSHIFT((SIGNED_VALUE)(x),1)) #define StringValuePtr(v) rb_string_value_ptr(&(v)) • Cから扱わない場合シンボルを宣言するのが大変 • 毎回「ruby.h」とかをがんばって読むことになる Ruby C APIではマクロが多用される
  • 14. Tsurami 3 fun rb_define_method(klass : VALUE, name : UInt8*, func : VALUE, VALUE -> VALUE, argc : Int32) • 関数の型を指定する必要がある • これ以外の型の関数を渡すとコンパイルエラー Ruby C API関数の引数が関数ポインタのとき…
  • 15. crystal_ruby Write Ruby extensions in Crystal. https://github.com/manastech/crystal_ruby • 公式による「Proof of Concept」 • 意識高い • 最新のCrystalでは動かすのにちょっと修正が要る
  • 16. Proof of Concept (PoC) ruby_extension "test_ruby", class Foo def foo(a) "From Crystal!! #{a}" end end ruby_extensionマクロでコード(文字列)を処理 マクロに渡されたコードはParserでパースされる
  • 17. Proof of Concept (PoC) class MyVisitor < Visitor … def visit(node : ClassDef) @str << %(_class = Ruby::Class.new "#{node.name}"n) end def visit(node : Def) @str << %(_class.def "#{node.name}", #{node.args.size}, ) @str << %[->(self : LibRuby::VALUE, ] node.args.each do |arg| @str << %(_#{arg.name} : LibRuby::VALUE, ) … end … end ASTノードはVisitorを継承したクラスで処理される 関数ポインタは型をVoid*で定義しておいて、ここで具体的な型として設定される
  • 19. Matome • Rubyの拡張をCrystalで書ける、が普通に書くとつらい • でも、Crystalで拡張を書く利点は大きい ‣ やっぱり速い ‣ Rubyのシンタックスと非常に近い • 公式がRubyの拡張に対して積極的