Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Java developer introduced to Rust-ADC2022

Takaichi00
November 29, 2022

Java developer introduced to Rust-ADC2022

Takaichi00

November 29, 2022
Tweet

More Decks by Takaichi00

Other Decks in Technology

Transcript

  1. Java 開発者が Rust に入門してみた
    #ADC2022
    髙市 智章 (Tomoaki Takaichi)
    Nov, 25, 2022 AItech Developer Conference 2022

    View Slide

  2. 自己紹介
    @Takaichi00
    tomoaki.takaichi.5
    ・髙市 智章(タカイチ トモアキ)
    ・2022/05 CA 入社
    ・エレベーターサイネージ
    ・Rust / Java でのシステム開発
    共著: クリーンなコードへの
    SonarQube即効活用術
    www.amazon.co.jp/dp/B086ML43DH

    View Slide

  3. 発表の流れ

    View Slide

  4. ❏ 主に Java を使ってきた自分にとって、Rust は今までにない概
    念が多く、つまずいたポイントがいくつもあった (今でもつまず
    き続けている)
    ❏ Rust を始める6ヶ月前の自分に対して、「Rust はこんな言語で
    すよ」「Rust と Java はこんな違いがありますよ」と伝えるよ
    うな発表をコンセプトにし、これから Rust を触ってみようとい
    う方の参考になれば
    発表をしようと思ったか

    View Slide

  5. Rust 言語とは

    View Slide

  6. ❏ 2015年に正式リリース
    ❏ 静的型付け・コンパイラ言語
    ❏ システムプログラミング言語
    ❏ C / C++ に匹敵する速度を実現し、OS, 組み込み, ブラウザなど低
    レイヤーを目的に作られた
    ❏ C 言語に加えて、Linux カーネルの開発向けプログラミング言語
    として採用される (Linux 6.1 から)
    Rust 言語

    View Slide

  7. Rust 言語
    ❏ しかしモダンな言語機能も搭載されており、高レイヤーまであつかう
    ことができる
    ❏ 2019年の Rust Survey によると、利用事例が一番多いのは
    ”Web バックエンドアプリケーション” となっている
    出典: https://blog.rust-lang.org/2020/04/17/Rust-survey-2019.html

    View Slide

  8. Rust 言語の特徴
    ❏ GC (ガベージコレクション) がない
    ❏ にも関わらず、メモリ安全+並行処理安全である
    ❏ ゼロコスト抽象化
    ❏ プログラミング言語が持つ抽象化 (ポリモーフィズム・高階関数 など) の
    機能をきる限り実行時ではなくコンパイル時に行うことで、実行速度の低
    下やメモリ使用量の増加を防ぐことができる
    ❏ 独自の仮想マシン (JVM など) を持たず、直接機械語にコンパ
    イルされる

    View Slide

  9. (軽く)
    Java 言語とは

    View Slide

  10. Java 言語とは
    ❏ 1996年に最初のバージョンがリリースされる (Rust 誕生の19
    年前!)
    ❏ 静的ページが主流だった当時、Java Applet を使えば簡単に動的ページが作れると
    いうところから人気を博す
    ❏ バイトコードにコンパイル → JVM がインタプリタ実行
    ❏ プラットフォームに依存しないプログラム開発
    ❏ GC / JIT コンパイラ がある
    ❏ エンタープライズシステムなどの利用例が豊富

    View Slide

  11. ここまでの説明を聞いた
    当時の感想

    View Slide

  12. Rust のファーストインプレッション
    よくわからないけど、Java より早くて C 言語よ
    り安全、モダンな言語機能もあるしバックエンド
    でもよく使われている。
    なんか行けそうな気がする!
    … でも、商用システムで使って大丈夫なの...?

    View Slide

  13. Rust で Web バックエンド
    アプリケーションを開発してみた

    View Slide

  14. (Java 以外の経験が少ない自分が)
    Rust でつまずいたポイント

    View Slide

  15. 基本文法でつまずく

    View Slide

  16. Rust と関数型言語
    ❏ Rust は関数型言語ではないが、関数型言語由来の文法や言語機
    能が多く採用されている
    ❏ これからお話する Result, Option, Iterator は関数型の機能 が
    元となっているが、慣れるまではコードを見ても何が起きてい
    るのかイメージしづらかった

    View Slide

  17. Result ・Option 型
    ❏ Rust には Go と同様に例外の機構はない
    ❏ エラーハンドリングには Result という列挙型 (関数型の Either が
    ベース) を使うか、パニックを起こして処理を強制終了させる方法がある
    ❏ 想定内のエラーであれば Result の Err を返すのが基本
    ❏ Rust には null 機能が存在しない
    ❏ これは安全性向上のための意図的な設計
    ❏ 存在するかしないかの値を表現したいときは Option という列挙型を利用
    する

    View Slide

  18. Result 型・Option 型と match 式
    ❏ Rust にはマッチしたパターンに応じてコードを実行させてくれ
    る強力な match 式があり、Result ・Option 型のハンドリン
    グもやろうと思えばすべて match 式で対応することができる
    ❏ 最初の頃はひたすら match 式で対応していたが、シンタックスシュガー
    を使いましょうとよく指摘される
    TODO: サンプルコード

    View Slide

  19. Result・Option 型 と シンタックスシュガー
    ❏ Result や Option 型は match 式以外にも様々なシンタックス
    シュガーを用いてハンドリングをすることができる
    ❏ しかし使いこなすまでには時間がかかった (今もなお苦戦中)
    ? 演算子

    View Slide

  20. Result + Option と Iterator の組み合わせ
    ❏ Rust には Java でいう Stream API のような、Iterator という
    Trait が提供されている
    ❏ Iterator と Option, Result 型などが組み合わさった処理は自分で書
    けるようになるまで更に時間がかかった

    View Slide

  21. 基本文法でつまずく
    ~関数型に慣れる必要がある~

    View Slide

  22. Rust 特有の概念でつまずく

    View Slide

  23. 「GC がない」 かつ 「メモリ安全」
    ❏ Rust には GC がないため、メモリ安全のコードを自前で実装し
    なければならない
    ❏ ただ Rust では「ライフタイム」「所有権」「借用」という仕組
    みを使うことで、メモリ安全ではないコードはコンパイルを通
    さないというアプローチをしている
    ❏ これにより、メモリ安全 + 高速な実行速度を実現している
    ❏ 多くの開発者はここに難しさを感じている
    ❏ 2020年の Rust Survey では、ライフタイム, 所有権・借用が Rust で難
    しいトピックの上位を占めていた

    View Slide

  24. 所有権
    ※ 今回は概略だけご説明します

    View Slide

  25. 所有権
    ❏ 所有権のルールは以下
    ❏ Rust の各値は、所有者と呼ばれる変数と対応している
    ❏ いかなるときも所有者は1つ
    ❏ 所有者がスコープから外れたら、値は破棄される

    View Slide

  26. 所有権
    ❏ 下記のコードは所有権が起因でコンパイルエラーになる代表例

    View Slide

  27. 所有権
    ❏ 関数に値を渡しても所有権が移り、下記コードはコンパイルエ
    ラーになる

    View Slide

  28. 所有権と借用
    ❏ いちいち関数に値を渡すたびに所有権がなくなるのは不便
    ❏ 関数に参照を渡すことで対応することができる (借用という)

    View Slide

  29. 所有権と Clone
    ❏ 借用の他にも、Clone という値を複製するメソッドを使うこと
    でも所有権をそのままにすることができる

    View Slide

  30. どのように所有権と向き合うか
    ❏ 何も意識せずに実装していくと、所有権が既に無いなどでよく
    コンパイラに怒られる
    ❏ 所有権の問題解決の勘所を押さえる
    ❏ 値を参照するだけであれば、参照を渡す
    ❏ Clone トレイトを用いて値を複製する
    ❏ メモリコストはかかるが、そこまでシビアに意識する必要が無
    ければこの方法で対応することが多い

    View Slide

  31. ライフタイム
    ※ 今回は概略だけご説明します

    View Slide

  32. ライフタイム
    ❏ ライフタイムとは、その参照が有効になるスコープのこと
    ❏ ライフタイムという仕組みによって、ダングリング参照 (解放済みの意
    図しないデータ参照など) を回避することができる

    View Slide

  33. ❏ Rust コンパイラには、スコープを比較して全ての借用が有効で
    あるかを決定する借用チェッカーというものがあり、これのお
    かげでダングリング参照をコンパイル時に弾いている
    ライフタイム

    View Slide

  34. ❏ 下記のコードは、実行するまで x と y のどちらの参照が戻り値
    の参照となるかわからない
    ❏ x と y のどちらのライフタイムが戻り値となるかコンパイラは
    わからないためエラーになる
    ライフタイム ~ 変数のスコープが切れない関数 ~

    View Slide

  35. ライフタイム ~ 変数のスコープが切れない関数 ~

    View Slide

  36. ❏ 下記の用にライフタイム注釈をつけることで、コンパイラは x
    と y の短い方のライフタイムを適用するということを知ること
    ができ、コンパイルが通る
    ライフタイム注釈

    View Slide

  37. ライフタイム注釈

    View Slide

  38. どのようにライフタイムと向き合うか
    ❏ ライフタイムは正直難しい... が、なるべくライフタイム注釈を
    利用しなくても済むような設計を心がける
    ❏ どうしてもライフタイムを意識して実装しなければならない場
    所は限られてくる
    ❏ ⇒ 要するにブロック内で変数のスコープが完結しない場合
    (関数で戻り値に参照を使う場合など)
    ❏ 基本的にはブロック内で変数を完結させるようにする
    ❏ できない場合は Clone で複製したり別の Struct を返すようにする

    View Slide

  39. Rust 特有の概念でつまずく
    ~存在を認知して、コンパイラに怒られながら進める~

    View Slide

  40. Web アプリケーション開発で
    つまずく

    View Slide

  41. ❏ Rust のライブラリ (Crate) 開発は活発ではあるが、比較的近年登場
    した言語のため、デファクトスタンダードがわからず、ライブラリ選
    定やテスティング手法で時間をかけることが多いと感じる
    ❏ オニオンアーキテクチャなどで DI をしたい場合、Java は Spring の
    強力な DI の仕組みに乗っかればいいが、今回採用した Rust の Web
    フレームワークである axum には汎用的な DI がなかったため、DI の
    仕組みを自作することに
    Web アプリケーション開発でつまずく
    ※ 時間の関係で詳しくはご説明できませんが、
    別途公開する資料や、サンプルコードなどをご覧になってみてください!

    View Slide

  42. Rust を触りたての頃の感想

    View Slide

  43. Java が恋しい!
    Java なら簡単なのに!
    Result,
    Option,
    iterator

    ライフタイム
    所有権
    借用

    DI の自作
    ライブラリ選定
    テスティング

    View Slide

  44. はたして本当に
    Java のほうが簡単なのだろうか?

    View Slide

  45. Java は Java で難しい部分がある

    View Slide

  46. Java の難しいところ ~ コンテナ化例
    ❏ 例えばコンテナ化をする際、Java では JVM という仕組みがあ
    るため以下のようなことを考慮する必要がある
    ● 起動時間を短くする工夫
    ● コンテナサイズを小さくする工夫
    ● コンテナ特有の JVM パラメータチューニング (GC どうするか、メモリ領域を
    それぞれどれくらい取ればいいか...など)
    ● JIT が十分にされていないとスループットが上がらないが、どれくらい暖気を
    すればいいのか...
    ※ Java でも GraalVM の Native Image を用いて実行可能ファイルを生成できるが 、機能が
    制限されたりコンパイル時間がとても長かったりと商用利用するには課題も多い

    View Slide

  47. Rust と Java のトレードオフ
    ❏ 実装の容易さという観点だけで見れば、Rust は Java よりも難
    易度は高く、開発生産性は Java のほうが高いかもしれない
    ❏ しかし運用という観点も含めると、Java は JVM のチューニン
    グやコンテナ化の工夫などが必須で、この分野は体系だった文
    献も少なく難易度は高い
    ❏ 加えて、LTS・ディストリビューション・サポート...など実際に運用する
    にあたっては考慮することが多い
    ❏ 一方 Rust はこのあたりを考慮する必要が Java に比べると圧倒
    的に少ない

    View Slide

  48. Rust と Java のトレードオフ
    ❏ パフォーマンスがある程度要求される場合での、実装と運用の
    学習コストの個人的な体感
    ❏ 「Rust は難しい」とよく言わ
    れている部分は実装難易度の部
    分が多いのでは
    ❏ ちゃんと運用のことも考えると
    Java の学習コストは結構高い

    View Slide

  49. Rust と Java のトレードオフ
    Rust Java
    実行速度・起動速度のチューニング ◯ ✕
    運用の難易度 ◯ ✕
    コンテナ化 ◯ ✕
    実装速度 ✕ ◯
    ライブラリ・ツールの成熟度 ✕ ◯
    開発者の確保のしやすさ ✕ ◯
    ❏ 個人的に感じる Rust と Java のトレードオフの関係の一例
    ※ 対比のため ✕ としているが全く向いていないということではなく、それぞれの言語で日々改善が行われている

    View Slide

  50. Java 開発者が Rust で
    開発してみた
    ~まとめ~

    View Slide

  51. ❏ 色々つまづきながらではあるが、Rust でも商用レベルのバック
    エンドの Web アプリケーションは実装できる
    ❏ Rust 特有の概念の理解や、実装のコツなどの学習コストは確か
    に低くはないが、その学習コストに見合うだけのメリットは教
    授できる
    ❏ 一部ツールなどで商用利用を開始しているが、Scala で実装された
    同機能よりも早い実行速度を実現できている
    Rust でも Web アプリケーションは実装できた

    View Slide

  52. ❏ 学習コストに対してパフォーマンスの恩恵が大きい → Rust
    ❏ ある程度のパフォーマンスが求められ、安定したチームで開発・運用し、
    学習の時間を確保できる場合は特に有効なのでは
    ❏ 今回のシステムでは上記を満たしていたので、Rust の技術選定は納得感
    が高い
    ❏ (自分の場合) 下記の条件下では使い慣れている Java を選択す
    るかも
    ❏ チームが流動的
    ❏ 期限がシビアかつパフォーマンスがそれほど求められない
    Rust と Java まとめ

    View Slide

  53. 学習方法・参考文献

    View Slide

  54. 出典: https://m.media-amazon.com/images/I/51Ks0DPW-oL.jpg
    参考文献 ~ 本
    出典: https://m.media-amazon.com/images/P/B07TQL7BB9.01._SCLZZZZZZZ_SX500_.jpg
    ● 原典が日本語で読みやすい
    ● Rust とはどういう言語か、CLI, 組み
    込み, WebAP などの実装例を体系的
    に学べる
    ● Rust のより詳細な言語仕様や実装方
    法について学ぶことができる

    View Slide

  55. 参考文献 ~ Web
    ● Rust Playground: https://play.rust-lang.org/
    ○ Web 上でコードを書いて簡単に実行できる
    ● Rust ツアー: https://tourofrust.com/chapter_1_ja.html
    ○ Web 上で基本文法を学べる
    ● 公式ドキュメント: https://doc.rust-jp.rs/book-ja/
    ○ 困ったときにはまずここを見る
    ● Rust CookBook: https://uma0317.github.io/rust-cookbook-ja/about.html
    ○ Rust での色々な実装例が記されている
    ● awesome-rust: https://github.com/rust-unofficial/awesome-rust
    ○ 用途に応じてどの Crate を使ったらいいかを非公式にリスト化しているもの
    ○ ORM にはどんな Crate があるか? といった探し方ができる
    ● 元 CA の豊田さんによるハンズオン資料:
    https://speakerdeck.com/helloyuk13/di-1hui-rust-hands-on-2b580ec5-fdd8-4210-bc6b-
    ff0549a1945d
    ● 業務で作った Rust ハンズオン: https://github.com/shoichi1023/rust-web-handson

    View Slide

  56. ❏ コンパイラに教えてもらう
    ❏ rust-analyzer に教えてもらう
    ❏ IDE 上で Rust の入力補完や文法ミスなどをサポート
    学習方法 ~ コンパイラと rust-analyzer ~
    コンパイラや rust-analyzer が表示するメッセージはわかりやすく、時には解決策も提示してくれる

    View Slide

  57. さいごに
    みなさんもぜひ Rust を使いましょう!!
    そして情報発信していただけると嬉しいです!!

    View Slide