Rustに入門したくて!
by
Masahiro Honma
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
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が常に速いとは限らない(言語速度<アルゴリズム)