Slide 1

Slide 1 text

TSのコードを Rustで書き直した話 2025.1.22 RustのLT会#3

Slide 2

Slide 2 text

asuka (@a_skua) ● 株式会社モニクル/SWE ○ Monicle Techbook vol.1 ● WebAssemblyの同人誌を書いている人 ○ WebAssemblyでできること ■ 商業誌:実践入門WebAssembly ○ ご注文はWASIですか? ○ ご注文はWASIですか?? ■ 商業誌:WebAssembly System Interface入門 ○ WebAssembly Cookbook vol.1 ○ WebAssembly Cookbook vol.2 ● 新宿御苑.devの運営,etc. ○ 新宿御苑.wasm #2025.2.28 やります 2 WHOAMI 技術書典14 技術書典15 技術書典16 技術書典17 WASIのまとまった情報あります↓↓ ↑↑SNSのアイコンの本

Slide 3

Slide 3 text

TSのコードをRustで書き直した話

Slide 4

Slide 4 text

TSのコードをRustで書き直した話 ● アドベントカレンダーの記事として投稿 ● 2024年に書いたZennの記事で一番伸びた 4 Node.jsのメモリ使いすぎ問題

Slide 5

Slide 5 text

Rustで書き直した結果... - 1プロセス400MB以上メモリを使用 + サーバー全体で40MB程度に - 1プロセス90秒程度かかっていた処理 + 1プロセス10秒未満に TSのコードをRustで書き直した話 ● アドベントカレンダーの記事として投稿 ● 2024年に書いたZennの記事で一番伸びた 5 Node.jsのメモリ使いすぎ問題

Slide 6

Slide 6 text

記事では計測結果しか書いていない Rustで書き直した結果... - 1プロセス400MB以上メモリを使用 + サーバー全体で 40MB程度に - 1プロセス90秒程度かかっていた処理 + 1プロセス10秒未満に TSのコードをRustで書き直した話 ● アドベントカレンダーの記事として投稿 ● 2024年に書いたZennの記事で一番伸びた 6 Node.jsのメモリ使いすぎ問題 今日話たいこと ● 良かったこと ● 大変だったこと ● 今後やりたいこと

Slide 7

Slide 7 text

良かったこと

Slide 8

Slide 8 text

1. 型やデータの責務がより明確になった 2. コーディング時のコードが読みやすくなった 良かったこと 8

Slide 9

Slide 9 text

1. 型やデータの責務がより明確になった 2. コーディング時のコードが読みやすくなった 良かったこと 9 TypeScript ● Prismaの型をそのまま使いがち問題 ● 結果Classを使わず,全てがObject ● Classの使い勝手が微妙 JS Rust ● struct と implで良い感じに type 手数料 = { 金額: number; 税率: number; is税抜き: boolean; }; function 税込手数料(手数料: 手数料): number { return is税抜き ? 手数料.金額 + (手数料.金額 * 手数料.税率) : 手数料.金額; } struct 手数料 { 金額: i32; 税率: i32; is税抜き: bool; ; impl 手数料 { fn 税込(&self) -> i32 { if self.is税抜き { self.金額 + (self.金額 * self.手数料.税率) } else { self.金額 } } }

Slide 10

Slide 10 text

1. 型やデータの責務がより明確になった 2. コーディング時のコードが読みやすくなった 良かったこと 10 TypeScript ● Prismaの型をそのまま使いがち問題 ● 結果Classを使わず,全てがObject ● Classの使い勝手が微妙 JS Rust ● struct と implで良い感じに const 税込 = 税込手数料(手数料); let 税込 = 手数料.税込(); JSにもclassはあるが,classだと面倒な場面が たまにあるあるのでobject使いがち 意味を正しく集約できた

Slide 11

Slide 11 text

type Foo = { a: number; b: number; }; type Bar = { a: number; b: number; }; 1. 型やデータの責務がより明確になった 2. コーディング時のコードが読みやすくなった 良かったこと 11 TypeScript ● Prismaの型をそのまま使いがち問題 ● 結果Classを使わず,全てがObject ● Classの使い勝手が微妙 JS Rust ● struct と implで良い感じに struct Foo { a: i32, b: i32, } struct Bar { a: i32, b: i32, } FooとBarは同じ型 FooとBarは異なる型 オブジェクトで曖昧だった値を型として意味を持たせることができた

Slide 12

Slide 12 text

1. 型やデータの責務がより明確になった 2. コーディング時のコードが読みやすくなった 良かったこと 12 TypeScript ● パターンマッチがない ● 所有権がない Rust ● パターンマッチがある ● 所有権がある impl Foo { fn 手数料(&self): Option { match (self.手数料1, self.手数料2, self.手数料3) { (Some(手数料1), _, _) => Some(手数料1), (None, Some(手数料2), _) => Some(手数料2), (None, None, 手数料3) => 手数料3, } } } function 手数料(foo: Foo): number | null { if (foo.手数料1 !== null) return foo.手数料1; if (foo.手数料2 !== null) return foo.手数料2; return foo.手数料3; }

Slide 13

Slide 13 text

1. 型やデータの責務がより明確になった 2. コーディング時のコードが読みやすくなった 良かったこと 13 TypeScript ● パターンマッチがない ● 所有権がない Rust ● パターンマッチがある ● 所有権がある fn 対象年齢(&self) -> bool { match self.年齢 { Some(年齢) => (20..=65).contains(&年齢), _ => false, } } function 対象年齢(年齢: number | null): boolean { return 年齢 !== null ? 20 <= 年齢 && 年齢 <= 65 : false; } シンプルな例だが,これらの書き換えの積み重ねでコードが読みやすくなった

Slide 14

Slide 14 text

class Foo { foo() {} bar() {} } impl Foo { fn bar(&self) {} fn baz(self) {} } 1. 型やデータの責務がより明確になった 2. コーディング時のコードが読みやすくなった 良かったこと 14 TypeScript ● パターンマッチがない ● 所有権がない Rust ● パターンマッチがある ● 所有権がある &selfとselfを使い分けれるのが嬉しい 頑張って気をつける

Slide 15

Slide 15 text

大変だったこと

Slide 16

Slide 16 text

1. 参照かクローンか 2. ビルド時間 3. スクラッチイメージの作成 大変だったこと 16

Slide 17

Slide 17 text

1. 参照かクローンか 2. ビルド時間 3. スクラッチイメージの作成 大変だったこと 17 JSのデータ構造のイメージをそのまま持って来れないケースはある interface Foo { bar: Bar } interface Bar {} struct Foo<'a> { bar: &'a Bar, } struct Bar {} これが意外と難しい

Slide 18

Slide 18 text

JSのデータ構造のイメージをそのまま持って来れないケースはある interface Foo { bar: Bar } interface Bar {} struct Foo<'a> { bar: &'a Bar, } struct Bar {} これが意外と難しい 1. 参照かクローンか 2. ビルド時間 3. スクラッチイメージの作成 大変だったこと 18 interface Foo { bar: Bar } interface Bar {} struct Foo { bar: Bar, } struct Bar {} とりあえずクローンすることにした

Slide 19

Slide 19 text

1. 参照かクローンか 2. ビルド時間 3. スクラッチイメージの作成 大変だったこと 19 Cloud Buildでビルドに16分ほどかかる

Slide 20

Slide 20 text

1. 参照かクローンか 2. ビルド時間 3. スクラッチイメージの作成 大変だったこと 20 Cloud Buildでビルドに16分ほどかかる 2vCPUから8vCPUに変更して約4分に短縮

Slide 21

Slide 21 text

1. 参照かクローンか 2. ビルド時間 3. スクラッチイメージの作成 大変だったこと 21 TLSライブラリの依存解決できなかったのでalpineベースで作成 それでも約22MBのコンテナイメージに収まった

Slide 22

Slide 22 text

今後やりたいこと

Slide 23

Slide 23 text

● cloneをなくす ● TSとRustのコードを1本化する 今後やりたいこと 23

Slide 24

Slide 24 text

● cloneをなくす ● TSとRustのコードを1本化する 今後やりたいこと 24 Rcなどに置き換える & データ構造を見直す

Slide 25

Slide 25 text

● cloneをなくす ● TSとRustのコードを1本化する 今後やりたいこと 25 RustからWasmにビルドしてTSのロジックを置き換える

Slide 26

Slide 26 text

2025.1.22 RustのLT会#3 TSのコードを Rustで書き直した話

Slide 27

Slide 27 text

同人誌 800円 27 今週土曜日1月25日),技書博11にて配布します 最新のWasmの動向を知りたい人向け 実装方法や活用事例など 商業誌 2,000円