如何保证在Powershell中实例化对象的顺序?

Bob*_*Bob 5 powershell multithreading

这是相当简单的代码块使用时间的Measure-Command[system.diagnostics.stopwatch]或通过版本比较了几个Get-Date电话,但这里的奇怪的事情;

当我包装Measure-Command两个日期对象时,有时Measure-Command.TotalMilliseconds长于($EndTime - $StartTime).TotalMilliSeconds

完成$EndTime之前是否实例化了对象Measure-Command

如果我运行单线程,为什么仍会发生这种情况?powershell.exe -sta

结束后是否有任何强制$EndTime设置的方法Measure-Command

StartTime之前有没有保证Measure-Command

显然,这种特定方法不是评估代码执行时间的明智方法。

$Stopwatch = [system.diagnostics.stopwatch]::startNew() 
$mc =Measure-Command{Invoke-WebRequest -Uri "http://www.google.com" -Method Head}
$Stopwatch.stop()


$mc.TotalMilliseconds
$Stopwatch.Elapsed.TotalMilliSeconds
"="
 $Stopwatch.Elapsed.TotalMilliSeconds - $mc.TotalMilliseconds


"`n"

$StartTime = (get-Date)
$mc = Measure-Command{Invoke-WebRequest -Uri "http://www.google.com" -Method Head}
$EndTime = (get-Date)

$mc.TotalMilliseconds
($EndTime - $StartTime).TotalMilliSeconds
"="
($EndTime - $StartTime).TotalMilliSeconds - $mc.TotalMilliseconds #This should never be negative but sometimes it is.

"`n"

$mc1 =Measure-Command{$mc2 = Measure-Command{Invoke-WebRequest -Uri "http://www.google.com" -Method Head}}

$mc1.TotalMilliseconds - $mc2.TotalMilliseconds 
Run Code Online (Sandbox Code Playgroud)

输出示例

122.3065
122.4322
=
0.125700000000009


142.8695
140.6371
=
-2.23240000000001


0.104199999999992
Run Code Online (Sandbox Code Playgroud)

Mat*_*sen 3

哦,天哪,这是很多有趣的问题,尽管我感觉您可能已经误入歧途,因为并非所有测量方法都是平等的 - 所以让我们来看看它们!

为什么我运行单线程还是会出现这种情况?powershell.exe -sta

因为这不是线程或并发问题

有没有办法强制结束$EndTime后设置Measure-Command

是的,通过将它们分成单独的语句(正如您已经完成的那样)

之前有没有$StartTime创建过任何保证Measure-Command

与之前的答案相同的根本原因;是的!

显然,这种特定方法不是评估代码执行时间的明智方法。

啊啊啊啊,你刚刚给了自己答案:)


DateTime.Now 是精确间隔测量的糟糕来源

Get-Date,不指定任何参数,返回值DateTime.Now

虽然DateTime.Now返回一个DateTime高精度的 struct 但它的值是通过查询操作系统的当前挂钟时间获得的,并且这种交互不会产生与其潜在精度相称的准确结果- 有关更多信息,我'建议阅读Eric Lippert 的这篇博文

如果您使用以下内容进行测试,您可能会看到很多“抖动”而不是正常的间隔分布:

$timestamp = Get-Date
0..9 |%{
    $timestamp - ($timestamp = Get-Date)
} |Select Ticks
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我什至比较的是Ticks属性而不是TotalMilliSeconds,得到的值(据说)是 10000 倍的精度 - 如果你进行比较,TotalMilleseconds你甚至可能在现代 PC 上得到 的结果0


Measure-Command内部使用 a StopWatch,后者又使用kernel32!QueryPerformanceCounterAPI,它提供了更精确的线性间隔测量源,因为它不受挂钟抖动和同步的影响 - 这正是您在[StopWatch]使用外测量

  • 做得很好; 奇怪的是,“DateTime”的准确性在 .NET Core 中似乎有所提高;OP 的症状不会在 PowerShell _Core_ 中出现。 (2认同)