PowerShell定时器/秒表精度

Loc*_*eds 6 powershell timer stopwatch

我发现System.Diagnostics.Stopwatch类具有看似可测量的不准确性,即使在很短的时间内(即20秒)也是如此.我的过程显示编码为运行20秒的进程的耗时20.3秒:

$elapsed = [System.Diagnostics.Stopwatch]::StartNew()
write-host "Started at $(get-date)"

for ($t=1; $t -le 20; $t++) {
    Write-Host "Elapsed Time: $($elapsed.Elapsed.ToString())"
    sleep 1
}

write-host "Ended at $(get-date)"
write-host "Total Elapsed Time: $($elapsed.Elapsed.ToString())"

    Started at 02/02/2013 15:08:43
    Elapsed Time: 00:00:00.0329924
    Elapsed Time: 00:00:01.0417435
    Elapsed Time: 00:00:02.0547547
    Elapsed Time: 00:00:03.0689716
    Elapsed Time: 00:00:04.0820497
    Elapsed Time: 00:00:05.0963413
    Elapsed Time: 00:00:06.1113915
    Elapsed Time: 00:00:07.1244044
    Elapsed Time: 00:00:08.1396105
    Elapsed Time: 00:00:09.1528952
    Elapsed Time: 00:00:10.1659905
    Elapsed Time: 00:00:11.1800884
    Elapsed Time: 00:00:12.1940009
    Elapsed Time: 00:00:13.2081824
    Elapsed Time: 00:00:14.2223585
    Elapsed Time: 00:00:15.2375023
    Elapsed Time: 00:00:16.2506360
    Elapsed Time: 00:00:17.2656845
    Elapsed Time: 00:00:18.2790676
    Elapsed Time: 00:00:19.2928700
    Ended at 02/02/2013 15:09:04
    Total Elapsed Time: 00:00:20.3080067
Run Code Online (Sandbox Code Playgroud)

在PowerShell中使用Stopwatch类时,这种精度是否会出现偏差?它似乎与时间跨度不成比例地增加(即10秒关闭0.1和20关闭0.3).我的代码有问题吗?

Ryn*_*ant 19

你有20秒1秒暂停,但你还有其他事情发生.有一个循环可以递增并测试变量,并在每次迭代时写入经过的时间.这些额外的事情需要时间.

这仍然有20秒的暂停,并且经过的时间接近20秒,因为PowerShell必须做的事情更少:

$elapsed = [System.Diagnostics.Stopwatch]::StartNew()
write-host "Started at $(get-date)"
sleep 20
write-host "Ended at $(get-date)"
write-host "Total Elapsed Time: $($elapsed.Elapsed.ToString())"
Run Code Online (Sandbox Code Playgroud)

  • 运行其他命令不会关闭秒表.运行其他命令需要更多时间; 因此,秒表显示正确的时间.使用秒表,这是准确的. (3认同)
  • 摆脱Started和Ended Write-Host调用,它应该更加接近.秒表使用Windows的高频计数器api,因此非常准确. (2认同)
  • 我想你错过了我的榜样.我试图证明`Diagnostics.Stopwatch`类不是不准确的.脚本中的秒表显示"20.3080067"秒的原因是因为你的脚本除了睡觉之外还在做其他事情.此外,"Get-Date"语句看起来恰好相隔20秒的原因是因为显示的时间四舍五入到最接近的秒. (2认同)

小智 2

问题是,你想做什么?如果您想确定脚本运行到底需要多长时间,您应该使用秒表。但是,如果您尝试在指定时间段后启动新的命令序列,请使用 [System.Timers.Timer] 并为计时器对象上的已用事件注册一个事件。然后将注册事件的操作指定为您想要完成的任务。