4

Perl でシステム時間をナノ秒単位で取得したかったのです。モジュールを試してみTime::HiResましたが、マイクロ秒までしかサポートしていません。

4

5 に答える 5

4

Time::HiResモジュールはマイクロ秒までサポートします。今日の一般的なハードウェアで@MarcoSが答えたように、ソフトウェアによってカウントされるナノ秒の精度を使用するのはナンセンスです。

2 つの後続の呼び出し、現在のマイクロ秒を取得し、その後両方を出力します。

perl -MTime::HiRes=time -E '$t1=time; $t2=time; printf "%.6f\n", $_ for($t1, $t2)'

結果(私のシステム上)

1411630025.846065
1411630025.846069

たとえば、現在の時刻を 2 回取得するだけで、3 ~ 4 マイクロ秒のコストがかかります。

「ナノ秒の数値」が必要な場合は、次のように 9 桁の精度で時刻を出力するだけです。

perl -MTime::HiRes=time -E '$t1=time;$t2=time; printf "%.9f\n", $_ for($t1, $t2)'

あなたは次のようになります:

1411630910.582282066
1411630910.582283974

かなりナノ秒です;)

とにかく、妥当なナノ秒の精度で眠ることができます。ドキュメントから

ナノスリープ ( $nanoseconds )

指定されたナノ秒 (1e9 秒) の間スリープします。実際にスリープ状態になったナノ秒数を返します (マイクロ秒単位まで正確であり、1,000 に最も近い単位です)。

...

nanosleep() が 1 ナノ秒まで正確であるとは思わないでください。1000ナノ秒の精度さえ得られるのは良いことです。

于 2014-09-25T07:30:40.470 に答える
3

Perl は Time::HiResを使用して時間を取得します

c:\Code>perl -MDateTime::HiRes -E "while (1) {say DateTime::HiRes->now()->strftime('%F %T.%N');}"

また

use Time::HiRes qw(time);
use POSIX qw(strftime);

my $t = time;
my $date = strftime "%F %T.%N", localtime $t;
$date .= sprintf ".%03d", ($t-int($t))*1000; # without rounding

print $date, "\n";
于 2014-09-25T07:08:15.410 に答える
0

根本的な問題は、Perl の Time::HiRes が通常の浮動小数点値を使用してタイムスタンプを表すことです。これは通常ネイティブ C として実装され、double多くのプラットフォームでは 64 ビットの IEEE float で、53 ビットの仮数部があります。

つまり、タイムスタンプは、1970 年からの距離に応じて異なる解像度で記録されます。

おおよその日付範囲 解像度
1969年11月13日~1970年2月18日 0.93ns未満 ナノ秒の分解能が利用可能
1969年9月25日 ~ 1970年4月8日 1.86ns
1969年6月20日~1970年7月14日 3.73ns
1968年12月08日 ~ 1971年1月24日 7.45ns
1967年11月16日 ~ 1972年2月16日 14.9ns
1961年7月~1978年6月 29.8ns
1978~1986 & 1953~1961 59.6ns
1987~2003 & 1936~1952 0.119μs
►</td> 2004~2037 & 1902~1935 0.238μs ◄</td>
2038~2105 & 1834~1901 0.477μs
2106~2242 & 1698~1833 0.954μs
1697年以前または2107年以降 マイクロ秒の解像度より悪い
于 2021-03-05T05:31:22.970 に答える