time: 継続時間、測定、待機時間
Durationの単位とrealtime・monotonic clockの違いを説明します。
Wave Foundation
Duration
std::time::durationのDurationにはsecondsとnanosecondsがあります。正規化されたnanosecondsの範囲は0から999999999までです。ミリ秒1000は1秒です。
time_duration_from_ms(milliseconds: i64) -> Duration
time_duration_from_seconds(seconds: i64) -> Duration
time_duration_checked_add(left: Duration, right: Duration) -> DurationResult
time_duration_to_ns(value: Duration) -> DurationValueResult
checked演算と整数変換結果にはokとvalueがあります。広いDurationを1つのi64ナノ秒の値に変更すると範囲を超える可能性があるため、okを最初に確認します。
測定と視覚の区別
std::time::clockのtime_now_realtime(tp: ptr<TimeSpec>) -> i64はカレンダー時刻に対応します。システム時刻補正に変更できるため、経過時間測定にはtime_now_monotonicを使用します。出力リポジトリは、呼び出し元によって提供され、ステータスが成功した場合にのみsec/nsecを読み込みます。
std::time::sleep
time_sleep(duration: Duration) -> i64
time_sleep_ms(ms: i64) -> i64
time_sleep_us(us: i64) -> i64
time_sleep_ns(ns: i64) -> i64
time_sleep_seconds(seconds: i64) -> i64
負の待機はエラーで、ゼロはすぐに成功します。 interruption以降はmonotonicdeadlineまでの残り時間だけ待機します。スケジューリングのため、実際に目が覚める時間が遅れる可能性があるため、正確な実行時間を保証する関数としては使用しません。 asyncタスク内で同期sleepを呼び出すとランチャーの進行を防ぐことができ、task::sleep_msを選択します。
単位変換の例
import("std::time::duration")::{
Duration, DurationValueResult, time_duration_from_ms, time_duration_to_ns
};
fun main() -> i32 {
var duration: Duration = time_duration_from_ms(1500);
var value: DurationValueResult = time_duration_to_ns(duration);
if (!value.ok) {
return 1;
}
println("{} {}", duration.seconds, duration.nanoseconds);
println("{}", value.value);
return 0;
}
実行結果:
1 500000000
1500000000
時間を加えて単位を変える
750msと800msを加えると1秒550000000ナノ秒です。秒とナノ秒をそれぞれ追加する代わりに、checked_addを使用すると、桁上げと表現範囲を一緒に調べることができます。
import("std::time::duration")::{
Duration,
DurationResult,
DurationValueResult,
time_duration_from_ms,
time_duration_checked_add,
time_duration_to_ms
};
fun main() -> i32 {
var first: Duration = time_duration_from_ms(750);
var second: Duration = time_duration_from_ms(800);
var sum: DurationResult = time_duration_checked_add(first, second);
if (!sum.ok) {
return 1;
}
var milliseconds: DurationValueResult = time_duration_to_ms(sum.value);
if (!milliseconds.ok) {
return 2;
}
println("{}s {}ns", sum.value.seconds, sum.value.nanoseconds);
println("{}ms", milliseconds.value);
return 0;
}
実行結果:
1s 550000000ns
1550ms
負の時間間隔
Durationは負の数も表現します。 -1msはseconds=-1、nanoseconds=999000000に正規化します。 2つのフィールドを合わせた値は負の1ミリ秒です。 nanoseconds フィールドのみ見て正数と判断してはいけません。
時間間隔計算では負数が有効ですが、sleepに負数を渡すのはエラーです。残りの待ち時間を計算する際に、すでに終了時刻を過ぎている場合は待機せずに次の処理に進む。
時間API選択
| 目的 | 選択 | 結果の意味 |
|---|---|---|
| 2つの視点間の経過時間 | monotonic clock | システム時刻補正と独立した間隔 |
| 実際のカレンダー時刻 | realtime clock | システムが設定した時刻 |
| 同期プログラムの待機 | time_sleep_ms |
コールフローが待機 |
| asyncジョブの待機 | task::sleep_ms |
他のタスクに実行する機会を引き渡す |
ナノ秒を返す時計でも実際の測定精度が1ナノ秒という意味ではありません。性能を比較するときは、短い操作を何度も繰り返した全時間を測定し、入出力のように測定対象とは無関係な作業は区間外に移動します。