2026年1月21日水曜日

FaaS(AWS Lambda)アプリケーションは、RustよりもGoで書く方が費用対効果が高いことが多いよ

昨年11月にAWS Lambdaでプログラミング言語Rustが正式サポートされたためであろうが、FaaSにRustが向いているという話がぼちぼちとされている*1。AWS Lambdaは起動・実行時間とメモリー割当量に応じて課金されるサービスで、高速で省メモリーのプログラミング言語に強みが出る用途だ。また、現在はARMアーキテクチャーの方が安いので、クロスコンパイルがしやすいと簡単にお得になる。

1. 安全、高速、省リソース

Rustは現在、最も注目されているプログラミング言語で、じわじわと用途を拡大している*2。メモリー安全で、最高水準の処理速度を誇り、メモリー利用量フットプリントも小さい。実行ファイルのサイズも小さい。近年人気のクロージャーやジェネリクスなどの文法の他、現代的なプロジェクト/パッケージ管理システムCargoもあるし、デバッガーなどの開発環境も整備されている。クロスコンパイルもできる。情報量が多く、生成AIに質問をしたら少なくともヒントになることを答えてくれて、公開されているライブラリやフレームワークも(用途によってはJavaやPHPやPythonにまったく届かない*3が)豊富だ。AWS Lambdaでも、Pythonなどに対してRustの処理速度とメモリーフットプリントは強みになる。

2. 所有モデルがもたらす困難

Rustにも弱点はあり、煩雑で人を選ぶ。メモリー安全の実現方法が、プログラマー・フレンドリーではない。コンパイラーがメモリー開放処理を自動で見えないところに書いてくれるのだが、いつメモリーの開放を行ってもよいかコンパイラーが分かるように、プログラマーはコードを記述しなければならない。所有、借用、スマートポインタ、ライフタイムと言った独特の概念を意識する必要がある。複雑なアプリケーションでは、忍耐力が必要だ。当たり前だが、構造体やリストやマップ(=ハッシュ/連想配列)も例外にならない。ほとんどのメモリー安全な人気プログラミング言語はガーベッジコレクターが自動で確保したメモリーの開放をしてくれるので、Rustよりも気楽に書ける。ボローチェッカー方式のメモリー安全だけではなく、マクロやアノテーションもあるシンプルではない文法であることも、コーディングに習熟していないプログラマーを困惑させる。

3. クラウド費用の削減 vs ソフトウェア開発費増

パブリッククラウドを使ったシステム開発にRustを採用すると、クラウド費用の削減と応答性能の向上が見込めるのは確かだ。簡単なRESTful APIのサービスだと、コンテナイメージのサイズは数MB、消費メモリー10MBに収めることもできる*4。PythonとJavaと比較すると、これは極端な例だが、二桁小さい。マイクロベンチマークを見ると、ライブラリに依存しない項目で、PythonやPHPやNode.jsの10倍、JavaとGoの2倍は速いことが多々ある。コールドスタートもPythonやJavaの1/5の時間で済む。反面、アプリケーション開発期間が伸びる。Pythonとその定番フレームワークが得意な種類のアプリケーションの場合、Rustによる開発は数倍どころではないぐらい余計に時間がかかる。そうでなくてもボローチェッカーと格闘することになれば、進捗が悪くなる。つまり、開発費は増える*5。プログラマーの確保にも困難がある。PythonプログラマーがRustに技術スイッチしてくれる気もあまりしない。

4. Goというバランス型の選択肢

Goではいけないのであろうか*6。Rustほどではないが、Goも省リソースで高速処理だ。クロスコンパイルはRustよりもしやすい。メモリーフットプリントが10MBが100MBになったとしても、最低料金の範囲であることは変わらない。処理速度も、実際はI/O待ちがあるため、何割かしか変わらない。コンテナイメージのサイズが数MBから数十MBになったとしても、PythonやJavaよりは一桁近く小さい。一方、GoはRustと異なり、学習コストが低く、開発が容易だ。ガーベッジコレクターによりメモリー安全性を実現し、マクロやアノテーションが存在しないなど文法が絞られている。逆に、使い勝手がよい機能がビルトインされている*7。PythonプログラマーがGoに技術スイッチすることも容易だ。生成AIでvibe codingすればRustもGoも変わらないような話もあるが*8、プログラマーは生成されたソースコードを検証して理解する必要は残るので、Rustの難易度の高さが解消されるわけではない。

5. 導入前によく検討が必要

Rustに移行しようと思った人は、使い慣れたPythonなどからスイッチ*9もしくはマイグレーション*10すべきほど、クラウドの応答性や費用に困っているかを再確認すべきだ*11。マイグレーションする場合は、本当に効果的なのか注意を払う必要がある。処理時間の大半がCなどの高速言語で書かれたライブラリーにかかっている場合、Rustに移行してもさほど効果は出ない。困っているとしても、難易度とのバランスがよいGoで間に合わないか考えるべきだ。もちろん、病的に最高のプロダクトを追求したいのであれば、Rustは有力な選択肢となる。

*1AWS LambdaはRustがおすすめ ー と言える時代が到来 #lambda - Qiita

*2米国国防高等研究計画局(DARPA)やマイクロソフト社はC/C++からRustへの移行を目指すとアナウンスしているし、Linuxカーネルの開発にも正式に使えるようになったし、AWSの構築にもRustが使われている。

*3有力MVCフレームワークが無いので画面が多数あるMPAの構築には向かない。Rustと性質の似ているGoの事例だが、PHP/Symfony、Python/Django、Ruby on RailsからGoに移行しようとして、開発効率の問題で移行中止した体験談があった。Java/Springからも、開発と運用に問題が生じたそうだ。逆にSPAのNode.jsからの場合は上手くいくことが多いようで、Rustの場合も同様であると予想される。

*4公開されているコード例をコンパイルしてコンテナーイメージにしたら、コンテナサイズは955KB、物理メモリー利用量940KBになった(Rust/axumで書いたRESTful APIのメモリーとディスクの使用量 - 餡子付゛録゛)。

*5保守費用はメモリー周りのバグが生じづらい事から、(C/C++と比較して)下がると言う指摘もある。パフォーマンス不足によるソフトウェア改修も起こりづらくなる。データベースのインデックスやSQL、クライアント(ブラウザー)のJavaScriptがボトルネックの場合は関係ないが。

*6Goも21世紀になってから登場したクラス型オブジェクト指向ではないプログラミング言語で、パッケージ管理システムを持ち、実行ファイルを生成する。

*7Goのdeferは確実にI/Oの接続を閉じるのに使える機能で、プログラマ負担も無い優れたものだが、Rustではscopeguardというパッケージで同等の機能が提供される。Rustはファイルハンドルを保持する変数がスコープを抜けると自動的にファイルクローズするようになっていたりするので、必要性は低くなっているが。goroutineも気軽に高度な並行処理を実現する機能だが、Rustではtokioパッケージなどを使わないといけない。ビルトインされておらず選択肢があり、例えばtokioではなくfuturesやasync-stdを選ぶこともできるので、突き詰めるのには良いわけだが。

*8Geminiに「RustのActix Webで、/htmlへのアクセスでは静的ページの内容を返し、/apiへのアクセスではRESTful APIとしてGET/POST/DELETE/UPDATEのそれぞれの処理を行うコード例を示してください。RESTful APIはオンメモリーのnameとnumberを要素に持つ構造体の配列データを操作するものとし、GETは一覧を、POSTはnumberの更新を、DELETEはnameをキーに削除を、UPDATEはnameをキーにnumberの更新をするものとします。」と指示したら、修正なしで動くコードが出てきた。

*9利用技術の転換。既存コードも書き換えるかは分からない。

*10既存コードの書き直し。

*112018年にGoがサポートされたのだが、2023年のDatadogの調査ではGoのサポートは1割未満で、Node.jsとPythonが人気のプログラミング言語であった。Goの強みの延長にあるRustがそこまで必要とされているかは疑わしい

0 コメント:

コメントを投稿