如果您确实需要亚秒级计时,那么对外部命令的任何调用,例如date
或读取外部系统文件,例如/proc/uptime
or /proc/rct
违背了亚秒级精度的目的。这两种情况都需要许多资源来检索所请求的信息(即时间)
由于 OP 已经使用了 GNU awk,因此您可以使用动态扩展。动态扩展是通过实现用 C 或 C++ 编写的新函数并使用 gawk 动态加载它们来向 awk 添加新功能的一种方法。如何编写这些函数在GNU awk 手册 https://www.gnu.org/software/gawk/manual/gawk.html#Dynamic-Extensions.
幸运的是,GNU awk 4.2.1 附带了一组默认的动态库,可以随意加载。这些库之一是time
具有两个简单功能的库:
the_time = gettimeofday()
以浮点值形式返回自 1970 年 1 月 1 日 UTC 以来经过的时间(以秒为单位)。若本平台无法提供时间,请返回-1
并设置ERRNO
. 返回的时间应具有亚秒级精度,但实际精度可能因平台而异。如果标准Cgettimeofday()
系统调用在此平台上可用,那么它只是返回值。否则,如果在 MS-Windows 上,它会尝试使用GetSystemTimeAsFileTime()
.
result = sleep(seconds)
尝试睡眠seconds
秒。如果seconds
为负数,或者睡眠尝试失败,返回-1
并设置ERRNO
。否则,在睡眠指定的时间后返回零。请注意,秒可能是浮点(非整数)值。实现细节:根据平台可用性,此功能尝试使用nanosleep()
or select()
来实施延迟。
source: GNU awk manual https://www.gnu.org/software/gawk/manual/gawk.html#Extension-Sample-Time
现在可以以相当简单的方式调用该函数:
awk '@load "time"; BEGIN{printf "%.6f", gettimeofday()}'
1553637193.575861
为了证明此方法比更经典的实现更快,我使用以下方法对所有 3 个实现进行了计时gettimeofday()
:
awk '@load "time"
function get_uptime( a) {
if((getline line < "/proc/uptime") > 0)
split(line,a," ")
close("/proc/uptime")
return a[1]
}
function curtime( cmd, line, time) {
cmd = "date \047+%Y/%m/%d %H:%M:%S.%N\047"
if ( (cmd | getline line) > 0 ) {
time = line
}
else {
print "Error: " cmd " failed" | "cat>&2"
}
close(cmd)
return time
}
BEGIN{
t1=getimeofday(); curtime(); t2=gettimeofday();
print "curtime()",t2-t1
t1=getimeofday(); get_uptime(); t2=gettimeofday();
print "get_uptime()",t2-t1
t1=getimeofday(); gettimeofday(); t2=gettimeofday();
print "gettimeofday()",t2-t1
}'
其输出:
curtime() 0.00519109
get_uptime() 7.98702e-05
gettimeofday() 9.53674e-07
虽然很明显的是curtime()
是最慢的,因为它加载外部二进制文件,令人惊讶的是 awk 在处理额外的外部 /proc/ 文件时速度非常快。