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 Hands-On 次の40年のためのプログラミング言語 第1回
Slide 2
Slide 2 text
自己紹介 Yuki Tw: @helloyuki_ • AI 事業本部所属のテックリード。 • Rust 領域における Next Experts。 • 外部での活動がこれまではメインだった。
Slide 3
Slide 3 text
Rust との出会い • 前職: 信用デリバや金利デリバなどのリスク管理計算機を作るエンジニアだった。 • 言語は Java 8 だった(プライシングエンジンまわりは C++)。 • 金融では大量のスレッドを使用した計算をする。 • Java でのマルチスレッド計算はかなり熟練した技術者でもバグを仕込みやすい。あと GC 、お前な。 • Rust を紹介(というか惜しみなく絶賛)する Googler の記事に出会う。 • 「こうすれば並行処理で苦労しないのに…」と思っていたアイディアが当時自分の中にあった。 • ぶっちゃけ GC なくなってくれない?安定しないんだけど?とちょっと思ってた。 • Rust は自分の思っていたアイディアを言語レベルでサポートしていることを知る。GC もない。 • この言語すごいなと思ってはじめた。
Slide 4
Slide 4 text
今日のゴール • Rust の解決したかったトレードオフを理解する。 • Rust のコンパイラが厳格な理由を理解する。 • どういった言語機能があるかを軽く理解する。 • 実際に環境構築をして Hello, World! する。
Slide 5
Slide 5 text
本日お話し すること • Rust はどのような言語か? • Rust の言語機能 • Rust を実際に動かしてみよう!
Slide 6
Slide 6 text
本日お話し すること • Rust はどのような言語か? • Rust の言語機能 • Rust を実際に動かしてみよう!
Slide 7
Slide 7 text
Rust はどの ような言語 か? • Rust 概要 • 言語の特長 • Rust の速さ • GC とメモリ安全 • ゼロコスト抽象化
Slide 8
Slide 8 text
Rust に どんなイメージがありますか? アンケート!
Slide 9
Slide 9 text
Rust 概要
Slide 10
Slide 10 text
どういう言語なのか? • 2015年にリリースされた新しい言語。 • 一言で言うなら「システムプログラミング言語である」。
Slide 11
Slide 11 text
システムプログラミング言語 • 担当領域が低レイヤーであるということ。 • OS、組み込み機器のファームウェア • コンパイラ、VM • 各種ミドルウェア • ブラウザ
Slide 12
Slide 12 text
しかし… • 言語設計が、モダンな言語機能の全部のせみたいなところがある。 • 特徴的な言語機能については後ほど解説します。 • 高級言語並みに表現力が豊かで快適にプログラミングできる。 • アンケートでは、Web バックエンドへの利用事例が実は多い。
Slide 13
Slide 13 text
2020年のRustの調 査 • Rust は毎年、言語に関するアンケー トを取っている。 • Webバックエンドの利用例が1位。 • 分散システム、組み込みデバイスな どが続く。 • 観測範囲では、仮想通貨やブロック チェーンでの利用例も多く感じる。 https://blog.rust-lang.org/2020/04/17/Rust-survey-2019.htmlより引用。 画像はランキングの一部を切り取り。
Slide 14
Slide 14 text
言語のカテゴライズ • 静的型付き言語。 • 型クラス指向あるいはムーブセマンティクス指向。 • マルチパラダイムプログラミング言語(Scala などが該当する)。 • 書き味は普通の命令型プログラミング言語(C や Java)。 • 関数型プログラミング言語ではない。
Slide 15
Slide 15 text
言語の特長 • 非常に実行速度が速く、パフォーマンスが安定的である。 • GC はないが、メモリ安全・並行処理安全である。 • メモリ安全: ダングリングポインタ、ヌルポインタなどが発生しない。 • 並行処理安全: データ競合が発生しない。 • 速度確保のために実装を歪める必要がない。
Slide 16
Slide 16 text
言語の特長 • 非常に実行速度が速く、パフォーマンスが安定的である。 • GC はないが、メモリ安全・並行処理安全である。 • メモリ安全: ダングリングポインタ、ヌルポインタなどが発生しない。 • 並行処理安全: データ競合が発生しない。 • 速度確保のために実装を歪める必要がない。
Slide 17
Slide 17 text
Rust の速さ ベンチマークゲームズを参考にして知る
Slide 18
Slide 18 text
C, Go, Java, Node.js, PHP, Python3, Swift を 実行速度の速い順に並べ替えてみてください! クイズ
Slide 19
Slide 19 text
Benchmark Games • 今回参考にするサイトは Benchmark Games というサイト。 • https://benchmarksgame-team.pages.debian.net/benchmarksgame/index.html • ここでいう速さとは、純粋にコード自体の実行時間のことを指している。
Slide 20
Slide 20 text
Rust の速さはいかほど? • Go や Java よりもさらに速い。 • C/C++ と並ぶかさらに速い。
Slide 21
Slide 21 text
Rust の速さはいかほど? • Go や Java よりもさらに速い。 • C/C++ と並ぶかさらに速い。
Slide 22
Slide 22 text
Rust の速さはいかほど? • Go や Java よりもさらに速い。 • C/C++ と並ぶかさらに速い。
Slide 23
Slide 23 text
なぜ速いのか? • 直接機械語にコンパイルされるから。 • ランタイムがないから。 • GC がないから。 • …など。
Slide 24
Slide 24 text
その他語られる話として • Rust には GC がない。 • このおかげで、メモリ使用量などの予測が立てやすい。 • GC の気まぐれでパフォーマンスが変わるといった影響を受けにくい。
Slide 25
Slide 25 text
この節のまとめ • Rust は地球上に存在する利用者の多い言語の中では最速の部類に入る。 • Rust の速さの根本要因は C/C++ と似た話になっている。 • GC がないこと。 • VM などを挟まず、機械語に直接コンパイルすること。
Slide 26
Slide 26 text
言語の特長 • 非常に実行速度が速く、パフォーマンスが安定的である。 • GC はないが、メモリ安全・並行処理安全である。 • メモリ安全: ダングリングポインタ、ヌルポインタなどが発生しない。 • 並行処理安全: データ競合が発生しない。 • 速度確保のために実装を歪める必要がない。
Slide 27
Slide 27 text
GC とメモリ安全
Slide 28
Slide 28 text
GC について、知っていることを教 えて下さい! アンケート!
Slide 29
Slide 29 text
GC のメリデメ メリット デメリット • メモリ管理を手動でしなくていい 。 • コード上にメモリ管理に関する追 加のノイズがなくなる。 • 多くのメモリに関する脆弱性は発 生しない。 • など • たとえばMark&SweepならSweep されるまでオブジェクトを解放で きない。 • ときどき一気にメモリが解放され る時間帯が発生し、その間はアプ リケーションが止まる。 • ランタイムを肥大化させやすい。 • など
Slide 30
Slide 30 text
Rust の領域と GC • Rust が担当する領域は、組み込みのファームウェアや OS になる。 • 計算資源が限られた環境で動くという前提がある。 • この制約下では、下記は困る。 • 言語自体がメモリを多く消費する設計になっている。 • ランタイムが大きい。 • フル GC などでアプリケーションを止められる。
Slide 31
Slide 31 text
メモリの手動管理は… • GC は選択肢にのぼらなくなるが、メモリの手動管理をする必要がある。 • 速度は段違いになる。 • メモリの手動管理はUB (Undefined Behaviour) を生みやすくなる。 • C/C++ 製のアプリケーションではよく UB 起因の脆弱性が報告される。 ※ サニタイザなどのツールの力を借りることはもちろんできる。 ※ C++11からはムーブセマンティクスが導入されたが、あれはあれでいくつか課題があった。
Slide 32
Slide 32 text
事例: Chromium Project • Chromium は C++ 製。 • メモリ関係の脆弱性が70%近くを 占める。 • ↓によるとコストは高い評価だが Rust も検討のテーブルに入ってい る。 どちらの画像も https://www.chromium.org/Home/chromium-security/memory-safety より引用
Slide 33
Slide 33 text
Rustの場合はどうしたか • Rust は GC を採用していない。 • Rust は「メモリ安全はコンパイラが検査する」で解決した。 • 「所有権」「ライフタイム」の仕組みで、メモリ安全でないコードはコンパイル時に弾く。 • 「コンパイラが厳しい」理由はここにある。 • この仕組みの裏側には型理論の研究成果が含まれている。 • こうしたメモリ安全・並行処理安全の仕組みは、第2回で詳しく説明する予定。 • 速度面と安全性のトレードオフを打破した。
Slide 34
Slide 34 text
この節のまとめ • 従来の言語では、メモリ安全のために GC を導入した。 • GC の導入は速度を犠牲にした。 • 従来の言語でのメモリの手動管理は、速度は追求できた。 • メモリの手動管理は安全性を犠牲にした。 • Rust はメモリ安全と速度の両立を実現した。
Slide 35
Slide 35 text
この節のまとめ • Rust はメモリ管理をコンパイラが自動で行う。 • メモリ安全でないコードはコンパイルが通らない。 • その分、余計な手間は増えている。 • コンパイルを通すのが難しくなる理由もここにある。 • というか、ソフトウェアを作るってそもそも難しい行為。 • 難しいが、すべてのプログラマが知っておくべき知識が可視化されている。
Slide 36
Slide 36 text
言語の特長 • 非常に実行速度が速く、パフォーマンスが安定的である。 • GC はないが、メモリ安全・並行処理安全である。 • メモリ安全: ダングリングポインタ、ヌルポインタなどが発生しない。 • 並行処理安全: データ競合が発生しない。 • 速度確保のために実装を歪める必要がない。
Slide 37
Slide 37 text
ゼロコスト抽象化
Slide 38
Slide 38 text
ゼロコスト抽象化とは • コードの抽象化を行ったとしても、追加のオーバーヘッドが発生しないこと。 • メモリ使用量が増加しない。 • 実行速度が低下しない。 • Rust における「抽象化」 • 多相性: ジェネリクス(パラメトリック多相)やトレイト(アドホック多相)。 • 高階関数: filter や map、あるいはクロージャを引数にとる関数。 • Future: 並行処理の抽象機構。
Slide 39
Slide 39 text
他のプログラミング言語では • 例: ジェネリクスを使用すると、動的ディスパッチによるオーバーヘッドが発生する。 • 実行時に関数の抽象と実装の紐付けを行う言語がほとんど。 • この方式を採用すると、紐付けを定義するテーブルの分のメモリ使用量が増える。 • 関数を呼び出す度にテーブルから探すので、その分のオーバーヘッドも増える。 • 例: for ループと for 内包表記とラムダは、全部実行速度が違う。 • 同じことを実現したいのに、採る手法によって実行速度が変わること全般を指す。 • いい例は Py …(おっと誰かが来たようだ。 • 全部実行速度が違うので、プログラマは適切な手法を知っていないとすぐオーバーヘッドが発生。
Slide 40
Slide 40 text
ゼロコスト抽象化のよさ • ゼロコスト抽象化のおかげで、下記のことは考慮しなくて良くなる。 • 抽象化すべき箇所で、実行速度を気にしてやめる。 • XXX という手法は速度が落ちる。YYY という手法を使うべき。 • ZZZ を採用すると、メモリ使用量が上がるから、AAA というハックをすべき。 • こういったワークアラウンドこそ、本当の意味での学習コストではないか? • 正直本質的ではない。 • 我々はコンピュータや実装と真正面から向き合いたい。 • ゼロコスト抽象化がないと C++ の代替は目指せないので、とても重要。
Slide 41
Slide 41 text
動的/静的ディスパッチ • 関数等の紐付けが実行時に解決されること。 • 動的型付き言語の大半。ダックタイピングみたいな。 • Java の implements X をしたとき、など。 • 都度解決する&参照のためにテーブルを探すので、遅い。 • ⇔静的ディスパッチ • 静的ディスパッチはコンパイル時に関数等の紐付けを解決すること。
Slide 42
Slide 42 text
Rust では • 基本的に静的ディスパッチが行われる。 • コンパイル時にジェネリクスの紐付けなどの型解決が行われる。 • 実行時には紐付け完了後のコードが走り、実行中に紐付けは行わない。 • あるキーワードを用いれば、動的ディスパッチもできる。
Slide 43
Slide 43 text
この節のまとめ • 従来の言語では、抽象化によるオーバーヘッドの発生が起きることがある。 • Rust では、ゼロコスト抽象化のおかげで、抽象化を妥協しなくてよい。 • 安心してメンテナンス性の高いコードを、速度面で妥協せず書くことができる。
Slide 44
Slide 44 text
言語の特長のまとめ • 非常に実行速度が速く、パフォーマンスが安定的である。 • GC はないが、メモリ安全・並行処理安全である。 • メモリ安全: ダングリングポインタ、ヌルポインタなどが発生しない。 • 並行処理安全: データ競合が発生しない。 • 速度確保のために実装を歪める必要がない。
Slide 45
Slide 45 text
Rust の言語機能 ササッと学ぶ!
Slide 46
Slide 46 text
みなさんの経験したプログラミング言語を教え て下さい アンケート
Slide 47
Slide 47 text
Hello, World
Slide 48
Slide 48 text
Hello, World • fn = 関数定義 • println! = マクロ
Slide 49
Slide 49 text
変数
Slide 50
Slide 50 text
制御構文 • if, for あたりは他の言語と同じように使える。 • Pattern Matching と呼ばれる switch 文の強力版が使える。 • 制御構文はすべて式(expression)な点に注意する。
Slide 51
Slide 51 text
制御構文
Slide 52
Slide 52 text
制御構文
Slide 53
Slide 53 text
制御構文
Slide 54
Slide 54 text
データ型の作り方 • 構造体を用いて新しいデータ型を定義する。 • enum を用いてデータを定義する。
Slide 55
Slide 55 text
データ型の作り方
Slide 56
Slide 56 text
データ型の作り方
Slide 57
Slide 57 text
エラーハンドリング • Result 型を用いた復帰可能なエラーハンドリングを行う。 • panic を用いて修復不能なエラーハンドリングを行う。 • 使い分けがよく議論の的になっている。
Slide 58
Slide 58 text
エラーハンドリング • 実用上は • プログラム自体の想定しないバグであれば panic しておく。 • 想定内のエラーであれば Result でハンドリングする。 • Java とのアナロジーで考えるなら(Rust には例外機構はないことに注意)、 • panic は非検査例外(RuntimeException) • Result は検査例外(Exception)
Slide 59
Slide 59 text
エラーハンドリング
Slide 60
Slide 60 text
エラーハンドリング
Slide 61
Slide 61 text
エラーハンドリング
Slide 62
Slide 62 text
抽象化の仕方 • 「トレイト」がキーワード。 • パラメトリック多相(ジェネリクス) • アドホック多相(型クラス) • 今回は説明しないが、dyn Trait や impl Trait というものもある。
Slide 63
Slide 63 text
パラメトリック多相
Slide 64
Slide 64 text
アドホック多相
Slide 65
Slide 65 text
メモリ管理の仕方 • 所有権、ライフタイム。 • ダングリングポインタを防止できる→安全性の源 • 今回は説明しないがスマートポインタ。
Slide 66
Slide 66 text
所有権
Slide 67
Slide 67 text
所有権
Slide 68
Slide 68 text
ライフタイム
Slide 69
Slide 69 text
ライフタイム
Slide 70
Slide 70 text
Rust のコンパイルエラー • わかりやすくない? • コンパイラの指示通りに直すと、安全で高速なコードが動く! • コンパイラは心強いもうひとりの同僚。
Slide 71
Slide 71 text
マクロ • 基本的には関数みたいなもの。 • メタプログラミングを可能にする。
Slide 72
Slide 72 text
マクロ
Slide 73
Slide 73 text
マクロ
Slide 74
Slide 74 text
マクロ
Slide 75
Slide 75 text
ユニットテスト • ファイル内に書ける。 • `cargo test` で標準で入っていて、それを叩くだけでよい。テストランタイムが不要。
Slide 76
Slide 76 text
ユニットテスト
Slide 77
Slide 77 text
unsafe • 生ポインタを参照できるようになる。 • 標準ライブラリの unsafe 関数を使用できる。 • unsafe キーワード • unsafe fn • unsafe trait • unsafe ブロック • unsafe ブロック内はコンパイラが安全性保証をしない。 • Rust は C/C++ の外部関数を呼び出す機能も持つ。
Slide 78
Slide 78 text
unsafe
Slide 79
Slide 79 text
Rust を実際に動かしてみよう! 今日一番大事!
Slide 80
Slide 80 text
Rust のインストール • https://www.rust-lang.org/ja/tools/install
Slide 81
Slide 81 text
プロジェクトを作る • cargo new hello-rust
Slide 82
Slide 82 text
Hello, World! • cd hello-rust • cargo run
Slide 83
Slide 83 text
エディタどうする? • ご自由にどうぞ。 • 黄金の組み合わせは VSCode に rust-analyzer をインストールすること。 • 今後のハンズオンもそれで行うので、使ってもらえるとトラブルシュートが早くなります。 • rust-analyzer 自体は Vim や Emacs でも使える。 • また、IntelliJ に Rust プラグインがあります。