报价不一致且波动
Ticks are inconsistent and are fluctuating
我有一个子程序和一个按钮。代码是这样的:
Private Sub plus(ByRef a As Integer)
For i = 0 To a
a = a + a
Next
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim i As Integer = 19
Dim sw As New Stopwatch
sw.Start()
plus(i)
sw.Stop()
MsgBox(sw.ElapsedTicks)
End Sub
当我运行子是通过点击"button1"程序输出310 就是说310是sw.elapsedticks
当我再次点击 "button1" 再次 运行 子时,程序输出 1 << JUST ONE ellapsedticks
怎么会这样?
我试图停止我的 vb.net 程序,我再次 运行 它,然后我再次点击它的按钮,它发生了同样的事情,这值得 272 秒表 elapsedticks 然后我再次点击stopwatch , elapsedticks 再次变为 1
请解释为什么会发生?
如果您的硬件不支持高性能计数器,StopWatch
class 将退回到使用 DateTime
class 并使用刻度进行测量。现在的大多数计算机,至少从 Windows 2000 年及以后,都有高性能计数器。考虑到这一点,.NET Stopwatch
class 就是基于这个高频计时器的。通常,调用 Start
查询性能计数器并存储值。当您 Stop
时,它会再次查询性能计数器。然后经过的时间是这两个值的简单减法,得到你的 ElapsedTicks
.
Here are a few items to have a look at for further explanation...
这个属性只是调用了GetRawElapsedTicks()
public long ElapsedTicks {
get { return GetRawElapsedTicks(); }
}
下面的函数 returns 从启动秒表到调用秒表 Stop
方法所经过的实际时间。如上所述,the elapsed time is a simple subtraction of those two values
你可以在下面看到:currentTimeStamp - startTimeStamp
.
// Get the elapsed ticks.
#if FEATURE_NETCORE
public long GetRawElapsedTicks() {
#else
private long GetRawElapsedTicks() {
#endif
long timeElapsed = elapsed;
if( isRunning) {
// If the StopWatch is running, add elapsed time since
// the Stopwatch is started last time.
long currentTimeStamp = GetTimestamp();
long elapsedUntilNow = currentTimeStamp - startTimeStamp;
timeElapsed += elapsedUntilNow;
}
return timeElapsed;
}
您可能会注意到上面的 #if FEATURE_NETCORE
并想知道它是什么。这些被称为预处理器命令。基本上它们的工作方式类似于 if-else
语句,除了如果不满足条件,它将不会在编译时包含代码,因为它是预编译决定而不是 运行time...
综上所述,Hans Passant 已经在上面提到了即时 (JIT) 编译。我上面提到的所有这些都进一步分解以进行解释。 差异的真正原因是它编译所花费的时间,运行 第一次.
还有一件事要提。 stopwatch
class 使用 long
变量类型来存储他们所谓的 frequency
。 Frequency"如果存在高分辨率性能计数器的频率,则存储TicksPerSecond。频率在系统运行ning期间不能改变,所以它只是初始化一次。
下面是其他 constants
,它们与频率及其计算方式有很大关系。
private const long TicksPerMillisecond = 10000;
private const long TicksPerSecond = TicksPerMillisecond * 1000;
当您创建 StopWatch
class 的新实例时,这就是 运行。
bool succeeded = SafeNativeMethods.QueryPerformanceFrequency(out Frequency);
if(!succeeded) {
IsHighResolution = false;
Frequency = TicksPerSecond;
tickFrequency = 1;
}
else {
IsHighResolution = true;
tickFrequency = TicksPerSecond;
tickFrequency /= Frequency;
}
如您现在所见,频率在设置如何计算已用时间以及如何计算方面起着重要作用tick
通常会发生。即使您停止应用程序也没有关系,因为此时已存储频率。 重置频率的唯一方法是重新启动您的机器。
我有一个子程序和一个按钮。代码是这样的:
Private Sub plus(ByRef a As Integer)
For i = 0 To a
a = a + a
Next
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim i As Integer = 19
Dim sw As New Stopwatch
sw.Start()
plus(i)
sw.Stop()
MsgBox(sw.ElapsedTicks)
End Sub
当我运行子是通过点击"button1"程序输出310 就是说310是sw.elapsedticks
当我再次点击 "button1" 再次 运行 子时,程序输出 1 << JUST ONE ellapsedticks
怎么会这样?
我试图停止我的 vb.net 程序,我再次 运行 它,然后我再次点击它的按钮,它发生了同样的事情,这值得 272 秒表 elapsedticks 然后我再次点击stopwatch , elapsedticks 再次变为 1
请解释为什么会发生?
如果您的硬件不支持高性能计数器,StopWatch
class 将退回到使用 DateTime
class 并使用刻度进行测量。现在的大多数计算机,至少从 Windows 2000 年及以后,都有高性能计数器。考虑到这一点,.NET Stopwatch
class 就是基于这个高频计时器的。通常,调用 Start
查询性能计数器并存储值。当您 Stop
时,它会再次查询性能计数器。然后经过的时间是这两个值的简单减法,得到你的 ElapsedTicks
.
Here are a few items to have a look at for further explanation...
这个属性只是调用了GetRawElapsedTicks()
public long ElapsedTicks {
get { return GetRawElapsedTicks(); }
}
下面的函数 returns 从启动秒表到调用秒表 Stop
方法所经过的实际时间。如上所述,the elapsed time is a simple subtraction of those two values
你可以在下面看到:currentTimeStamp - startTimeStamp
.
// Get the elapsed ticks.
#if FEATURE_NETCORE
public long GetRawElapsedTicks() {
#else
private long GetRawElapsedTicks() {
#endif
long timeElapsed = elapsed;
if( isRunning) {
// If the StopWatch is running, add elapsed time since
// the Stopwatch is started last time.
long currentTimeStamp = GetTimestamp();
long elapsedUntilNow = currentTimeStamp - startTimeStamp;
timeElapsed += elapsedUntilNow;
}
return timeElapsed;
}
您可能会注意到上面的 #if FEATURE_NETCORE
并想知道它是什么。这些被称为预处理器命令。基本上它们的工作方式类似于 if-else
语句,除了如果不满足条件,它将不会在编译时包含代码,因为它是预编译决定而不是 运行time...
综上所述,Hans Passant 已经在上面提到了即时 (JIT) 编译。我上面提到的所有这些都进一步分解以进行解释。 差异的真正原因是它编译所花费的时间,运行 第一次.
还有一件事要提。 stopwatch
class 使用 long
变量类型来存储他们所谓的 frequency
。 Frequency"如果存在高分辨率性能计数器的频率,则存储TicksPerSecond。频率在系统运行ning期间不能改变,所以它只是初始化一次。
下面是其他 constants
,它们与频率及其计算方式有很大关系。
private const long TicksPerMillisecond = 10000;
private const long TicksPerSecond = TicksPerMillisecond * 1000;
当您创建 StopWatch
class 的新实例时,这就是 运行。
bool succeeded = SafeNativeMethods.QueryPerformanceFrequency(out Frequency);
if(!succeeded) {
IsHighResolution = false;
Frequency = TicksPerSecond;
tickFrequency = 1;
}
else {
IsHighResolution = true;
tickFrequency = TicksPerSecond;
tickFrequency /= Frequency;
}
如您现在所见,频率在设置如何计算已用时间以及如何计算方面起着重要作用tick
通常会发生。即使您停止应用程序也没有关系,因为此时已存储频率。 重置频率的唯一方法是重新启动您的机器。