Rustに入門したくて!
by
Masahiro Honma
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Slide 1
Slide 1 text
Rustに入門したくて! perl-xsでXSを書き始めた話 hiratara
Slide 2
Slide 2 text
Rustに入門したい理由 おっさんプログラマの(以下略)
Slide 3
Slide 3 text
XSは難しい ● XS言語がむずかしい ● C言語がむずかしい ● Perl APIがむずかしい
Slide 4
Slide 4 text
XSは難しい MODULE = Sum PACKAGE = Sum void sum(...) PPCODE: { if (items != 2) { croak("Invalid argument count: %d", items); } SV *a = ST(0); SV *b = ST(1); IV ret = SvIV(a) + SvIV(b); XPUSHs(sv_2mortal(newSViv(ret))); XSRETURN(1); }
Slide 5
Slide 5 text
perl-xs ● rustのクレート ● PerlXS API のラッパー ● rustだけでPerl拡張が書ける
Slide 6
Slide 6 text
perl-xs use perl_xs::IV; xs! { package Sum::RS; sub sum(ctx, a: IV, b: IV) { a + b } }
Slide 7
Slide 7 text
用意するもの ● cpanfile ● Makefile.PL ● lib/Foo/Bar.pm ● src/lib.rs
Slide 8
Slide 8 text
cpanfile ● Module::Install::Rust ○ Makefile.PL の記述に必要 ● Ouroboros ○ perl-xs クレートが必要
Slide 9
Slide 9 text
Makefile.PL use inc::Module::Install; name "Sum-RS"; version "0.01"; abstract "Tests for perl-xs"; configure_requires "Module::Install::Rust" => 0; requires "XSLoader" => 0; rust_use_perl_xs { git => "https://github.com/vickenty/perl-xs" }; rust_requires "perl-sys" => { git => "https://github.com/vickenty/perl-sys" }; rust_requires "perlxs_derive" => { git => "https://github.com/vickenty/perl-xs" }; rust_write; WriteAll;
Slide 10
Slide 10 text
lib/Foo/Bar.pm package Sum::RS; use strict; use warnings; require XSLoader; XSLoader::load();
Slide 11
Slide 11 text
src/lib.rs #[macro_use] extern crate perl_xs; #[macro_use] extern crate perl_sys; mod fib { use perl_xs::IV; xs! { package Sum::RS; sub sum(ctx, a: IV, b: IV) { a + b } } } xs! { bootstrap boot_Sum__RS; use fib; }
Slide 12
Slide 12 text
例1: フィボナッチ数列 (perl) sub fib { return 1 if $_[0] <= 2; fib($_[0] - 1) + fib($_[0] - 2); }
Slide 13
Slide 13 text
例1: フィボナッチ数列 (perl-xs) use perl_xs::IV; fn fib_(n: i32) -> i32 { if n <= 2 { 1 } else { fib_(n - 1) + fib_(n - 2) } } xs! { package Fib::RS; sub fib(ctx, n: IV) { fib_(n as i32) as IV } }
Slide 14
Slide 14 text
例1: フィボナッチ数列 $ carton exec -- 'perl -Mblib benchmarks/fib.pl' (warning: too few iterations for a reliable count) Rate pp rs pp 3.74/s -- -99% rs 500/s 13260% --
Slide 15
Slide 15 text
例2: PUBLIC SUFFIX LIST ● .com, .co.jp, .jp, .*.compute.amazonaws.com など ○ クッキーを設定できないドメイン ● Domain::PublicSuffix ○ https://metacpan.org/pod/Domain::PublicSuffix ● publicsuffix ○ https://github.com/rushmorem/publicsuffix
Slide 16
Slide 16 text
例2: PUBLIC SUFFIX LIST $ carton exec -- 'perl -Mblib benchmarks/domain_public_suffix.pl' Rate pp rs pp 78740/s -- -9% rs 86957/s 10% -- あれ、たいして速くないじゃん・・・
Slide 17
Slide 17 text
遅い理由 ● rust の publicsuffix の実装が遅い ● perl-xs が遅い
Slide 18
Slide 18 text
publicsuffixが遅い ● 線形検索してる ○ 修正済: https://github.com/rushmorem/publicsuffix/pull/20 ● 余分な処理がある ○ ドメインのフォーマットのバリデーション ○ ユニコード周りの処理 $ carton exec -- 'perl -Mblib benchmarks/domain_public_suffix.pl' (warning: too few iterations for a reliable count) Rate pp rs pp 77519/s -- -71% rs 270270/s 249% --
Slide 19
Slide 19 text
perl-xsが遅い ● Ouroboros のオーバヘッド(マクロの関数化) ● 例外処理のオーバヘッド IV ouroboros_sv_iv(pTHX_ SV* sv) { return SvIV(sv); } int perl_sys_hv_iternext(HE** RETVAL, HV * hv) { int rc = 0; dJMPENV; JMPENV_PUSH(rc); if (rc == 0) { *RETVAL = hv_iternext(hv); } JMPENV_POP; return rc; }
Slide 20
Slide 20 text
perl-xs のまとめ ● rustだけで書けて楽 ● PerlとRustが切り替わる箇所はそれなりに遅い ● PerlよりRustが常に速いとは限らない(言語速度<アルゴリズム)