Синхронизация с использованием javascript performance.now()

Я пытаюсь рассчитать время выполнения моей функции в миллисекундах. Я использую performance.now() для этого. Я могу получить время при первом запуске, но при втором, третьем и т. Д. Я получаю 0 миллисекунд. Вот пример:

function someFunction (){
    var t0 = performance.now();
    //Function calculations
    var t1 = performance.now();
    Console.log(t1 - t0);
}

Я запускаю функцию onclick. Это работает, когда я впервые запускаю страницу. Перестает работать на втором клике. t0 и t1 получают одинаковые значения, и когда я вычитаю их, я получаю 0 за время. Есть ли что-нибудь вокруг этого? Мне не обязательно использовать performance.now(). Я просто хочу измерять время в миллисекундах.

Спасибо.

Обновление Я думаю, что это все, что связано со скоростью. Например:

    <html>
    <script type="text/javascript">
     function someFunction (){
        var t0 = performance.now();
        console.log(t0);
        //Function calculations
        //Some loop
        var counter = 0;
        for (i = 0; i < 1000000; i++) { 
         counter ++;
     }
        var t1 = performance.now();
        console.log(t1);
        console.log(t1 - t0);
    }
    
    </script>
    
    <button type="button" onclick="someFunction()">Click me</button>
    </hmtl>

Работает, как и следовало ожидать, но с циклом for (i = 0; i < 1000; i++) это не так.

Спасибо за указатели в правильном направлении.

1 ответ

Фактический код, который вы используете, изменит здесь результаты, и почему тест доходит до 0, как результат, является вопросом спекуляции без этого.

Тем не менее, микро тесты в JavaScript в наши дни подлежат оптимизации. Например:

function spiffy() {
    /* long bit of code that
       loops and loops and runs in 
       O(n!) time then finally */ 
    return result; 
}

Spiffy!

Скажем spiffy() детерминистически всегда выводит один и тот же результат. Оптимизатору разрешено эффективно запускать это как:

function spiffy() { 
    return 42; 
}

Который превращается

function someFunction (){
    var t0 = performance.now();
    var result = spiffy();
    var t1 = performance.now();
    Console.log(t1 - t0);
}

в бесполезный результат теста.

Если у вас есть истинная проблема с производительностью в вашем приложении JavaScript, я бы профилировал его, когда оно работает медленнее, чем патока, и проанализировал бы самые загруженные части вашего кода. И я имею в виду не микро-тесты, а изучение времени выполнения, посмотрите на алгоритм, который вы используете в этом разделе, и посмотрите, может ли он быть лучше для ваших обстоятельств, и, наконец, спросите кого-то еще о реальном коде в вопрос, в том же контексте он работает.

Согласно документу MDN:

https://developer.mozilla.org/en-US/docs/Web/API/Performance/now

Отметка времени не является на самом деле высоким разрешением. Чтобы смягчить угрозы безопасности, такие как Spectre, браузеры в настоящее время в разной степени округляют результаты. (Firefox начал округлять до 1 миллисекунды в Firefox 60.) Некоторые браузеры также могут слегка рандомизировать временную метку. Точность может снова улучшиться в будущих выпусках; Разработчики браузеров все еще изучают эти временные атаки и способы их смягчения.

В таком случае не стоит полагаться на performance.now() в браузерах, или полагаться только на разрешение в миллисекундах (например, Date.now() делает).

Один обходной путь, оборачивая ваш код другим for{} цикл в 1000 раз, поэтому время, затрачиваемое на упакованный код, примерно в 1000 раз больше исходного кода.

function benchmark(func) {
  var start = Date.now()
  for (var i=0;i<1000;i++) {
    func();
  }
  var end = Date.now();
  var diff = (end - start) / 1000;
  console.log('running 1000 times, average time is '+ diff + 'ms');
}
benchmark(someFunction);

Или вы можете проверить свой код в NodeJS, если в вашем коде нет операции DOM:

  • process.hrtime()
  • performance.now

performance.now() обновлен и вопрос должен быть закрыт и больше не сталкиваться

https://developer.mozilla.org/en-US/docs/Web/API/Performance/now

метки времени, возвращаемые Performance.now(), не ограничены разрешением в одну миллисекунду. Вместо этого они представляют времена как числа с плавающей точкой с точностью до микросекунды.

  <html>
        <script type="text/javascript">
         function someFunction (){
            var t0 = performance.now();
            console.log(t0);
            //Function calculations
            //Some loop
            var counter = 0;
            for (i = 0; i < 1000; i++) { 
             counter ++;
         }
            var t1 = performance.now();
            console.log(t1);
            console.log(t1 - t0);
        }
        
        </script>
        
        <button type="button" onclick="someFunction()">Click me</button>
        </hmtl>

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