Rust/WebAssemblyのトラブルに効くデバッグ&高速化テクニック
Rust言語で作るWebバイナリファイル「WebAssembly」入門 第5回
ダウンロード サンプルファイル (2.4 MB)
プログラムの実行時間を測定するログ出力
ログ出力時に時間を測定して表示させることもできます。計算の繰り返し回数を指定して円周率を計算する、図4のサンプルで利用方法を説明します。円周率を計算する処理の詳細は第3回も参照してください。
このサンプルではプログラムの実行時間を測定するために、JavaScriptの「window.performance.nowメソッド」と「console.time / timeEndメソッド」を利用しています。それぞれをRustから利用するための実装内容を以下で説明します。
Webページ表示からの経過時間を返すwindow.performance.nowメソッド
window.performance.nowメソッドは、Webページを表示してからの経過時間をミリ秒で返却するJavaScriptのメソッドです。図4で「実行1」をクリックすると、このメソッドを利用して測定した時間が、図5の通りコンソールに出力されます。
window.performance.nowメソッドをRustから利用するには、console.logやerrorメソッド同様、web_sysクレートを利用して、リスト8の通り実装します。
fn now() -> f64 {
web_sys::window() //(1)
.expect("should have a Window") //(2)
.performance() //(3)
.expect("should have a Performance") //(4)
.now() //(5)
}
(1)で、web_sys::window()メソッドを実行して、WindowオブジェクトのOptionを取得します。Optionは、ある値が存在するかどうかを表す列挙型で、(2)のexpectメソッド実行時に値(ここではWindowオブジェクト)が存在すればそれを返却し、存在しなければexpectメソッドの引数に指定した文言とともにパニックを起こします。そのため、(3)のperformanceメソッドを実行する時点では、Windowが存在することが保証されます。performanceメソッドの戻り値についても(4)のexpectでPerformanceの存在を検証してから、(5)のnowメソッドを実行します。この一連の記述により、JavaScriptのwindow.performance.nowメソッドをRustから実行できます。
サンプルコードではリスト9の処理で、繰り返し計算10万回ごとに、処理開始からの時間をコンソールに出力します。
let start_time = now(); // 処理開始時間
(略)
if i % 100000 == 0 {
// 現在の時間を取得
let cur_time = now();
// 現在の時間-処理開始時間をコンソールに出力
web_sys::console::log_1(&format!("itr[{}]: {}", i, cur_time - start_time).into());
}
なお、リスト8、9を実行するには、web_sysでWindow、Performanceを利用することを明示的にCargo.tomlに記述する必要があります(リスト10)。
[dependencies.web-sys] version = "0.3" features = [ "console", "Window", # 追加 "Performance" # 追加 ]
特定処理の間の時間を計るconsole.time / timeEndメソッド
console.timeメソッドとtimeEndメソッドは、特定処理の間の時間を計るJavaScriptのメソッドです。console.timeメソッドを呼んでからtimeEndメソッドを呼ぶまでの時間が取得できます。図4で「実行2」をクリックすると、このメソッドを利用して測定した時間が、図6の通りコンソールに出力されます。
console.time / timeEndメソッドをRustで利用するには、リスト11の通り、web_sys::console::time_with_labelおよびconsole::time_end_with_labelメソッドを利用します。
// 時間計測を開始 ...(1)
web_sys::console::time_with_label("console.time/timeEndを利用");
while i <= count {
(略)
// 100,000ループに1回、時間を計測
if i % 100000 == 0 {
// 時間計測を終了 ...(2)
web_sys::console::time_end_with_label("console.time/timeEndを利用");
// 次の時間計測を開始 ...(3)
web_sys::console::time_with_label("console.time/timeEndを利用");
}
(略)
}
// 時間計測を終了 ...(4)
web_sys::console::time_end_with_label("console.time/timeEndを利用");
(1)や(3)のtime_with_labelメソッド実行時から時間計測が開始され、(2)や(4)のtime_end_with_labelメソッド実行時に計測した時間をコンソールに出力します。引数のラベルが同じtime_with_labelとtime_end_with_labelメソッドが対になります。
この記事は参考になりましたか?
- Rust言語で作るWebバイナリファイル「WebAssembly」入門連載記事一覧
-
- Rust/WebAssemblyのトラブルに効くデバッグ&高速化テクニック
- Rust/WebAssemblyとJavaScriptのデータ交換を使いこなす!
- Rustでわかる! WebAssemblyのメリット~処理速度の違いを、サンプルを作りなが...
- この記事の著者
-
WINGSプロジェクト 吉川 英一(ヨシカワ エイイチ)
<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
