Клещи непоследовательны и колеблются
У меня есть саб и кнопка. И код такой:
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 секунд секундомера, затем после повторного нажатия секундомера, вместо этого снова будет 1
Пожалуйста, объясните, почему это могло произойти?
1 ответ
StopWatch
класс отступит от использования DateTime
Класс и использует отметки для измерений, если ваше оборудование не поддерживает высокопроизводительный счетчик. Большинство современных компьютеров, по крайней мере из Windows 2000 и более поздних версий, имеют высокопроизводительные счетчики. Имея это в виду,.NET Stopwatch
класс основан на этом высокочастотном таймере. В общем звонит Start
запрашивает счетчик производительности и сохраняет значение. Когда ты Stop
, он снова запрашивает счетчик производительности. Тогда прошедшее время - это простое вычитание этих двух значений, чтобы дать вам ElapsedTicks
,
Вот несколько пунктов, чтобы взглянуть на них для дальнейшего объяснения...
Это свойство просто звонит GetRawElapsedTicks()
public long ElapsedTicks {
get { return GetRawElapsedTicks(); }
}
Приведенная ниже функция возвращает фактическое время, прошедшее с момента запуска секундомера до момента его включения. 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
утверждения, за исключением того, что если условие не выполнено, оно не будет включать код во время компиляции, так как это решение до компиляции, а не во время выполнения...
С учетом всего вышесказанного Ханс Пассант уже упоминал выше о своевременной компиляции (JIT). Все это, что я упомянул выше, приводит к дальнейшему объяснению. Настоящая причина разницы - это время, необходимое для компиляции и запуска в первый раз.
Еще одна вещь, чтобы упомянуть. stopwatch
класс использует long
тип переменной для хранения того, что они называют frequency
, Частота "сохраняет частоту счетчика производительности с высоким разрешением, если он существует, в противном случае он будет хранить TicksPerSecond. Частота не может измениться во время работы системы, поэтому она инициализируется только один раз.
Ниже приведены другие constants
которые имеют большое значение с частотой и как она рассчитывается.
private const long TicksPerMillisecond = 10000;
private const long TicksPerSecond = TicksPerMillisecond * 1000;
Когда вы создаете новый экземпляр StopWatch
класс это то, что побежал.
bool succeeded = SafeNativeMethods.QueryPerformanceFrequency(out Frequency);
if(!succeeded) {
IsHighResolution = false;
Frequency = TicksPerSecond;
tickFrequency = 1;
}
else {
IsHighResolution = true;
tickFrequency = TicksPerSecond;
tickFrequency /= Frequency;
}
Частота, как вы можете видеть, играет большую роль в определении того, как будет рассчитываться прошедшее время и как часто tick
будет происходить. Даже когда вы останавливаете свое приложение, это не имеет значения, так как частота сохраняется в это время. Единственный способ сбросить частоту - это перезагрузить компьютер.