Клещи непоследовательны и колеблются

У меня есть саб и кнопка. И код такой:

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 будет происходить. Даже когда вы останавливаете свое приложение, это не имеет значения, так как частота сохраняется в это время. Единственный способ сбросить частоту - это перезагрузить компьютер.

Другие вопросы по тегам