GoogleがAndroidの開発にRustを使った事例を解説するRust Dayを開催
Googleが2022年8月9日に「Rust Day on Open Source Live」と呼ばれるオンラインイベントを開催した。今回はRustに特化した1時間半のセミナーの動画からエッセンスを紹介する。
●Google Open Source live動画:https://www.youtube.com/watch?v=SU8clrSVWtI
このセッションではAndroidの開発チームのエンジニアによるプレゼンテーションとして、Androidのコードベースの一部をRustで書き直した事例、ビルドプロセスにおけるRust採用のポイント、Linux KernelにおけるRust採用について、最後にWOFF2というフォントの圧縮/非圧縮を行うプログラムをC++から書き直した事例の概要という内容を1時間半にわたって紹介するものだ。
最初に登場したのはLars Bergstrom氏、Android Plarformのプログラミング言語担当のディレクターという肩書のエンジニアだ。
Bergstrom氏はRustの特長の紹介に合わせて、Androidには並列処理が高速に行えることが重要だとして、その上に安全性、つまりメモリーセーフ関連のバグを起こさないことが必要だと語り、Rustがその要求を満たしていることを説明した。
スマートフォンのOSには高速性とスレッドとメモリーにおける安全性が必要なことに加えて様々なCPUが使われること、並列処理が必須となると説明。その上でAndroidがどうしてRustを使うようになったのか? という点においては何よりもセキュリティが重要だったとして、Androidにおけるセキュリティに関わるバグのうち、約60%がメモリーセーフ関連だったことを紹介。これにはアナライザーやハードウェアによる保護だけでは補うことができなかったと解説した。
その上でAndroidのBluetooth関連のソフトウェアを開発しているチームのテクニカルリードを務めるエンジニアの証言として「Rustに移行した後は、コンパイルさえ終ってしまえば、意図しない処理によってシステムが暴走しないことから本来のBluetoothの処理に専念できる」というコメントを紹介した。
この部分を更に強調するためにC++で書かれたコードとRustで書かれたコードを比較し、非同期のループ処理がシンプルに記述できることを紹介した。
また20年以上におよ及ぶC++の経験を持つセキュリティチームのテクニカルリードからは「Rustを1年以上書いた経験から、C++のコンパイラーが意図しない動作をすることを認めているということに我慢するのは馬鹿らしい」というコメントを紹介した。このコメントはAndroidの開発チームの中でRustに移行する価値をベテラン程認めていることを強調していると言える。
ただし技術的に優れているからと言ってビジネスの根幹となるAndroidの開発に使うという決断は行えなかったとして、ここからはビジネスサイドのニーズにも注目して評価を行ったことを説明した。
特に、すでに何百万行もC++のソースコードが存在するのに、それを新しい言語で置き換える価値はあるのか? という問いには、メモリーセーフ関連のバグが何年間コードの中に存在していたのか? を検証した結果、新しいコードに顕著に現われていることを解説。つまりツールが追加され機能が高くなったとしてもバグは最新のコードから発生していることを表している。結論としてバグを出さないためにはこれ以上CやC++で新しい機能を実装することを止めることが必要、Rustがバグの発生を抑える最大の抑止力になると語った。
また既存のコードベースとの共存、ビルドシステムとの連携、どのプロジェクトから始めるのか? といった部分にも注意が必要だと解説。プロジェクトの選択にはいつでも元の言語に戻れるという選択肢があることが大事だったと説明した。またRustを知らないエンジニアが大多数の場合、コアとなる小さなグループを作り、そこから徐々に増やす方法を採用したと説明。ソフトウェアエンジニアが潤沢に存在するGoogleのAndroidチームでも慎重にRust化が行われたことを示している。
このスライドはコードベースを管理する立場から、Rustに移行する際の戦略を解説。いつでもロールバックできること、ゴールはRustに書き換えることではなくより良いビジネス面での目標を達成すること、実験的に行っていることを意識すること、振り返りを常に行うこと、小さなチームで始めることなどが挙げられている。
このスライドでは、新規に開発されるコードベースと既に存在するコードベースにそれぞれRustを適用するとしたらどのような部分が適しているのか? を解説している。FFI(Foreign Function Interface)によって外部のコードとしてRustを呼び出す場合と、新たにコードをRustで書き下ろす場合で違うことを解説している。より具体的には、新規に書く場合にはデータベースやファイルシステムへの入出力処理、プロセス間の通信などが発生する部分に採用するべきだと説明。これはパラメータなどによってデータの受け渡しが発生する部分にメモリーセーフバグが発生しがちであることの予防という意味があるのかもしれない。
それを図で示したものが次のスライドだ。
また従来のコードの一部を書き直す場合、Rustが持つUnsafeの機能を使ってデータの受け渡しを行うことが必要になることがあるが、その際にもなるべくUnsafeを使わないで呼び出しを行うべきと説明。RustでUnsafeを使うとC++よりもエラーを起こす可能性が高まることを指摘した。
ビルドシステムにおいても既に存在するコードリポジトリ、crates.ioを使うこと、標準となっているCargoをツールチェーンの中に連携させることを推奨している。
Cargoが優れたビルドシステムであることを紹介しながら、他にもBazelのCrate UniverseやFacebookが開発、公開しているReindeerなども紹介した。ちなみにCrate UniverseもReindeerもリポジトリーとしてはcrates.ioを使っている。
この部分の最後として、大きなプロジェクトであっても小さな部分から書き直し始めること、書き直すことを目的にしないこと、戦略を立てること、Unsafeな使い方をしないことなどを挙げて締めくくった。
次は、RustをLinux Kernelに採用するという内容に関するセッションだ。
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- RustConfで見えてきたRustプロジェクトが最も大事にする価値とは?
- ISRGが推進するメモリーセーフなソフトウェアを増やすための地道なプログラムProssimoを紹介
- RustNL 2024からデータ圧縮ライブラリーzlibをRustで書き直したプロジェクトのセッションを紹介
- 高速でメモリーセーフなプログラミング言語、Rustの特徴を紹介
- データ処理ライブラリーの並列化/高速化をRustによって実装したWeld
- RustNLからマルチプラットフォームのアプリ開発のためのツールRobiusのセッションを紹介
- DropboxがコアサービスをRustで書き換えた背景とは
- RustConfからTwitterがキャッシュサーバーをRustで書き直したセッションを紹介
- Microsoftの年次イベントBuild 2020でメモリーセーフなプログラミング言語Rustを紹介
- Rustと非同期ライブラリーTokioで作成した簡易版Redisを紹介