Синхронизация с использованием 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>