プログラムの実行時間を測定するログ出力
ログ出力時に時間を測定して表示させることもできます。計算の繰り返し回数を指定して円周率を計算する、図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メソッドが対になります。