Как измерить время выполнения функции

1192

Мне нужно получить время выполнения в миллисекундах.

Первоначально я задавал этот вопрос еще в 2008 году. Тогда был принят новый ответ: использовать Date (). GetTime (). Однако теперь мы все можем согласиться с тем, что использование стандартного API performance.now () более целесообразно. Поэтому я меняю принятый ответ на этот.

Юлий А
источник
3
Часто утверждение о том, что вы пытаетесь выполнить со временем выполнения, может оказаться гораздо более полезным, чем ответ на один вопрос. В наши дни использование инструментов профилирования в Firebug или Chrome Dev часто является гораздо лучшим способом найти код, который поглощает ваш процессорный сок.
oligofren
вот как вы можете сделать это классическим Dateспособом, который дает вам msи достаточно для большинства случаев, я думаю, albertech.blogspot.com/2015/07/… ... но да, вы действительно должны смотретьPerformance.now
jar
5
performance.now()не работает в Node. new Date().getTime()будет работать в узле.
Райан Уокер
1
номер 1000 upvote woop woop: D
Kiksen
1
@oligofren - иногда вы можете захотеть получить эти данные. У меня есть ситуации , когда я пишу это IndexedDB
ThomasRones

Ответы:

1757

Использование performance.now () :

var t0 = performance.now()

doSomething()   // <---- The function you're measuring time for 

var t1 = performance.now()
console.log("Call to doSomething took " + (t1 - t0) + " milliseconds.")

NodeJs: требуется импортироватьperformance класс


Использование console.time :(Нестандартные)(уровень жизни )

console.time('someFunction')

someFunction() // Whatever is timed goes between the two "console.time"

console.timeEnd('someFunction')

Примечание :
Строка существо передача доtime()иtimeEnd()методы должны совпадать
(для таймера до конца , как и ожидалось).

console.time() Документации:

  1. Документация NodeJS относительно
  2. MDN (клиентская) документация
VSync
источник
27
Теперь он поддерживается и Chrome Developer Tools.
julien_c
3
В настоящее время это лучший способ собрать точные данные из того, что я понимаю.
Эш Блю
6
Вам не нужно выполнять функцию между этими двумя операторами? Теперь вы измеряете время, необходимое для его определения, а не для его выполнения. Поправь меня, если я ошибаюсь ...
Кристиан
2
Ссылка на статью MDN об этой функции: developer.mozilla.org/en-US/docs/DOM/console.time
nullability
6
да, вы можете сделать `totalTime + = console.timeEnd ('timer') 'и сделать это для каждого таймера
vsync
637

использовать новый Date (). getTime ()

Метод getTime () возвращает количество миллисекунд с полуночи 1 января 1970 года.

ех.

var start = new Date().getTime();

for (i = 0; i < 50000; ++i) {
// do something
}

var end = new Date().getTime();
var time = end - start;
alert('Execution time: ' + time);
Оуэн
источник
9
Обратите внимание, что вы можете заменить + new Date () на вызов getTime (): var start = + new Date (); // сделать сообщение о предупреждении («Время выполнения:» + (+ new Date ()) - начало);
J c
55
Время не является точным, потому что Дата не предназначена для этой функции. Я собираюсь быть смелым здесь и сказать, что вы должны использовать пример vsync, если вы хотите точные сроки. Хотя он работает только в банкоматах Chrome и Firefox.
Эш Блю
9
Осторожно, getMilliseconds () дает вам доли миллисекунды текущей секунды. Если вы замените getTime () на getMilliseconds (), вы можете получить отрицательные результаты, если пересечете секунду.
RickyA
6
Ответ от vsync является гораздо более правильным по сегодняшним стандартам, и использование Date () может привести к отображению очень ошибочных результатов, особенно на платформе Windows, где результаты могут быть округлены + смещены до ближайшей границы 15 мс, что приводит к странным вещам, таким как Время 0 мс на крошечных битах кода.
oligofren
29
@AshBlue, мы должны использовать window.performance.now. См stackoverflow.com/a/15641427/632951
Pacerier
405

Не используйте Date (). Читай ниже.

Используйтеperformance.now() :

<script>
var a = performance.now();
alert('do something...');
var b = performance.now();
alert('It took ' + (b - a) + ' ms.');
</script>

Работает на:

  • IE 10 ++

  • FireFox 15 ++

  • Chrome 24 ++

  • Safari 8 ++

  • Опера 15 ++

  • Android 4.4 ++

  • и т. д.

console.timeможет быть жизнеспособным для вас , но это нестандартное § :

Эта функция является нестандартной и не соответствует стандартам. Не используйте его на рабочих сайтах, выходящих в Интернет: он не будет работать для каждого пользователя. Также могут быть большие несовместимости между реализациями, и поведение может измениться в будущем.

Помимо поддержки браузера, performance.nowкажется, есть потенциал для обеспечения более точных сроков, поскольку это, кажется, пустая версия console.time.


<rant> Также НИКОГДА не используйте Dateдля чего-либо, потому что это зависит от изменений в «системном времени». Что означает, что мы будем получать некорректные результаты -кака «отрицательное времени» - когда пользователь не имеет точное время системы:

В октябре 2014 года мои системные часы вышли из строя и угадайте, что .... Я открыл Gmail и увидел все электронные письма моего дня, отправленные 0 минут назад ". И я думал, что Gmail должен быть создан инженерами мирового уровня из Google .......

(Установите системные часы на год назад и перейдите в Gmail, чтобы мы все могли посмеяться. Возможно, когда-нибудь у нас будет Зал позора для JSDate .)

Google Spreadsheet's now()Функция также страдает от этой проблемы.

Единственное время, которое вы будете использовать, Dateэто когда вы хотите показать пользователю его системное время. Не тогда , когда вы хотите получить на время или для измерения ничего.

Pacerier
источник
3
Как раз то, что я искал! Я хочу иметь возможность добавлять несколько раз вместе, на самом деле я не могу сделать это с помощью времени консоли.
Рэй
8
обратите внимание, что это еще не поддерживается в сафари: developer.mozilla.org/en-US/docs/Web/API/Performance.now ()
Akos K
2
Я использую Firebug Profile и performance.now (), и они оба работают хорошо. Performance.now () подтверждает мой результат из профиля.
Винсент Цзя
2
Не работает в моем самом большом зависании - IE7 (корпоративные клиенты). Меня не волнует измерение производительности в Chrome, оно всегда молниеносно.
Ник
2
Это лучший способ, чем console.time ().
Санджеев
52

Если вам нужно получить время выполнения функции на вашем локальном компьютере разработки , вы можете использовать инструменты профилирования вашего браузера или консольные команды, такие как console.time()иconsole.timeEnd() .

Все современные браузеры имеют встроенные профилировщики JavaScript. Эти профилировщики должны давать наиболее точные измерения, поскольку вам не нужно изменять существующий код, что может повлиять на время выполнения функции.

Для профилирования вашего JavaScript:

  • В Chrome нажмите F12 и выберите вкладку « Профили », затем выберите « Сборка профиля ЦП JavaScript». .
  • В Firefox установите / откройте Firebug и нажмите на Профиль .
  • В IE 9+ нажмите F12 , нажмите Script или Profiler (в зависимости от вашей версии IE).

Кроме того, на своем компьютере разработки вы можете добавить инструментарий в свой код с помощью console.time()и console.timeEnd(). Эти функции, поддерживаемые в Firefox11 +, Chrome2 + и IE11 +, сообщают о таймерах, через которые вы запускаете / останавливаете console.time(). time()принимает заданное пользователем имя таймера в качестве аргумента, а timeEnd()затем сообщает о времени выполнения с момента его запуска:

function a() {
  console.time("mytimer");
  ... do stuff ...
  var dur = console.timeEnd("myTimer"); // NOTE: dur only works in FF
}

Обратите внимание, что только Firefox возвращает прошедшее время в timeEnd()вызове. Другие браузеры просто сообщают результат на консоль разработчика: возвращаемое значениеtimeEnd() не определено.

Если вы хотите узнать время выполнения функции , вам придется использовать свой код. У вас есть пара вариантов. Вы можете просто сохранить время начала и окончания, выполнив запрос new Date().getTime():

function a() {
  var start = new Date().getTime();
  ... do stuff ...
  var end = new Date().getTime();
  var dur = end - start;
}

Однако Date объект имеет разрешение только в миллисекундах и будет зависеть от изменений системных часов любой ОС. В современных браузерах есть лучший вариант.

Лучший вариант - использовать High Resolution Time , иначе window.performance.now(). now()лучше традиционного Date.getTime()в двух важных аспектах:

  1. now()является двойным с субмиллисекундным разрешением, которое представляет количество миллисекунд с начала навигации по странице. Возвращает количество микросекунд в дробной части (например, значение 1000.123 равно 1 секунде и 123 микросекундам).

  2. now()монотонно увеличивается. Это важно, поскольку при последующих вызовах Date.getTime()может произойти скачок вперед или даже назад. Примечательно, что если системное время ОС обновляется (например, синхронизация атомных часов), Date.getTime()также обновляется. now()гарантированно всегда будет монотонно увеличиваться, поэтому на него не влияет системное время ОС - оно всегда будет временем настенных часов (при условии, что ваши настенные часы не атомарные ...).

now()может быть использован практически в каждом месте , что new Date().getTime(), + new DateANDT Date.now()есть. Исключением является то , что Dateи now()времена не смешиваются, так как Dateоснован на Unix-эпохи (количество миллисекунд с 1970 года), в то время как now()это число миллисекунд , прошедших с вашей страницы навигации началась (так он будет гораздо меньше , чемDate ).

Вот пример того, как использовать now():

function a() {
  var start = window.performance.now();
   ... do stuff ...
  var end = window.performance.now();
  var dur = end - start;
}

now()поддерживается в стабильных Chrome, Firefox 15+ и IE10. Также доступно несколько полифилл .

Еще одна опция для измерения времени выполнения в дикой природе - UserTiming . UserTiming ведет себя так же, как console.time()и console.timeEnd(), но использует ту же now()метку времени с высоким разрешением, которая использует (так что вы получаете монотонно увеличивающиеся часы на доли миллисекунды), и сохраняет метки времени и длительности в PerformanceTimeline .

UserTiming имеет понятия меток (временных меток) и мер (длительностей). Вы можете определить столько, сколько хотите, и они отображаются на PerformanceTimeline .

Чтобы сохранить метку времени, звоните mark(startMarkName). Чтобы узнать длительность с момента первой отметки, просто позвоните measure(measurename, startMarkname). Затем продолжительность сохраняется в PerformanceTimeline вместе с вашими отметками.

function a() {
  window.performance.mark("start");
  ... do stuff ...
  window.performance.measure("myfunctionduration", "start");
}

// duration is window.performance.getEntriesByName("myfunctionduration", "measure")[0];

UserTiming доступен в IE10 + и Chrome25 +. Есть также доступный polyfill (который я написал).

NicJ
источник
1
Отличный и самый актуальный ответ ИМХО :) Было бы еще лучше с небольшим редактированием. Я бы сказал , что выбор времени пользователь не «один другой вариант» для измерения, но предпочтительный вариант , когда сравнительный анализ не делается на самой машине развития. С вашим polyfill он работает во всех браузерах. И скрывая детали и шаблон и является причиной его существования. performance.nowDate
hashchange
34

Чтобы получить точные значения, вы должны использовать интерфейс производительности . Он поддерживается в современных версиях Firefox, Chrome, Opera и IE. Вот пример того, как его можно использовать:

var performance = window.performance;
var t0 = performance.now();
doWork();
var t1 = performance.now();
console.log("Call to doWork took " + (t1 - t0) + " milliseconds.")

Date.getTime()или console.time()не подходят для точного измерения времени выполнения. Вы можете использовать их, если вам подходит быстрая грубая оценка. Под грубой оценкой я имею в виду, что вы можете получить 15-60 мс сдвиг от реального времени.

Посмотрите этот блестящий пост по измерению времени выполнения в JavaScript. Автор также дает пару ссылок о точности времени JavaScript, которое стоит прочитать.

Варвара Калинина
источник
Очень хороший ответ! Это мне очень помогло!
Объединить
18

Используйте Firebug, включите и консоль, и Javascript. Нажмите Профиль. Reload. Нажмите Профиль еще раз. Посмотреть отчет.

Стефан Май
источник
8
Хороший совет, но, очевидно, работает только для FF. Мы часто хотим сравнивать скорости браузера ... :-)
PhiLho
3
В новом Firebuq они скрывают эти параметры в меню, используя CTRL + SHIFT + P или console.profile (); console..profileEnd ()
user956584
4
Chrome поддерживает console.time()и console.timeEnd()тоже сейчас.
julien_c
12
var StopWatch = function (performance) {
    this.startTime = 0;
    this.stopTime = 0;
    this.running = false;
    this.performance = performance === false ? false : !!window.performance;
};

StopWatch.prototype.currentTime = function () {
    return this.performance ? window.performance.now() : new Date().getTime();
};

StopWatch.prototype.start = function () {
    this.startTime = this.currentTime();
    this.running = true;
};

StopWatch.prototype.stop = function () {
    this.stopTime = this.currentTime();
    this.running = false;
};

StopWatch.prototype.getElapsedMilliseconds = function () {
    if (this.running) {
        this.stopTime = this.currentTime();
    }

    return this.stopTime - this.startTime;
};

StopWatch.prototype.getElapsedSeconds = function () {
    return this.getElapsedMilliseconds() / 1000;
};

StopWatch.prototype.printElapsed = function (name) {
    var currentName = name || 'Elapsed:';

    console.log(currentName, '[' + this.getElapsedMilliseconds() + 'ms]', '[' + this.getElapsedSeconds() + 's]');
};

эталонный тест

var stopwatch = new StopWatch();
stopwatch.start();

for (var index = 0; index < 100; index++) {
    stopwatch.printElapsed('Instance[' + index + ']');
}

stopwatch.stop();

stopwatch.printElapsed();

Вывод

Instance[0] [0ms] [0s]
Instance[1] [2.999999967869371ms] [0.002999999967869371s]
Instance[2] [2.999999967869371ms] [0.002999999967869371s]
/* ... */
Instance[99] [10.999999998603016ms] [0.010999999998603016s]
Elapsed: [10.999999998603016ms] [0.010999999998603016s]

performance.now () является необязательным - просто передайте false в функцию конструктора StopWatch.

kayz1
источник
12

process.hrtime () доступен в Node.js - он возвращает значение в наносекундах

var hrTime = process.hrtime()
console.log(hrTime[0] * 1000000 + hrTime[1] / 1000)
Ахим Кёльнер
источник
1
если вы предпочитаете конвертировать его в ms e-3, а не в предложенную микросекунду e-6: hrtime[0] * 1000 + hrtime[1] / 1000000-> да, я тоже использую var hrtime! : P
cregox
11

Вы можете использовать оператор добавления также здесь

 var start = +new Date();
 callYourFunctionHere();
 var end = +new Date();
 var time = end - start;
 console.log('total execution time = '+ time + 'ms');
Алок Дешвал
источник
8

Для дальнейшего расширения кода vsync, чтобы иметь возможность возвращать timeEnd в качестве значения в NodeJS, используйте этот маленький кусочек кода.

console.timeEndValue = function(label) { // Add console.timeEndValue, to add a return value
   var time = this._times[label];
   if (!time) {
     throw new Error('No such label: ' + label);
   }
   var duration = Date.now() - time;
   return duration;
};

Теперь используйте код так:

console.time('someFunction timer');

someFunction();

var executionTime = console.timeEndValue('someFunction timer');
console.log("The execution time is " + executionTime);


Это дает вам больше возможностей. Вы можете сохранить время выполнения, которое будет использоваться для других целей, таких как использование его в уравнениях или сохранение в базе данных, отправка удаленному клиенту через веб-сокеты, обслуживание на веб-странице и т. Д.

Леви Робертс
источник
8

Можно использовать только одну переменную:

var timer = -performance.now();

// Do something

timer += performance.now();
console.log("Time: " + (timer/1000).toFixed(5) + " sec.")

timer/1000 - конвертировать миллисекунды в секунды

.toFixed(5) - обрезать лишние цифры

user1032559
источник
5

Так как console.timeи performance.nowне поддерживаются в некоторых основных браузерах (например, IE10), я создал тонкую утилиту, которая использует лучшие доступные методы. Тем не менее, он не обрабатывает ошибки для ложных использований (вызовEnd() неинициализированного таймера).

Используйте его и улучшайте как хотите.

Performance: {
    Timer: {},
    Start: function (name) {
        if (console && console.time) {
            console.time(name);
        } else if (window.performance.now) {
            this.Timer[name] = window.performance.now();
        } else {
            this.Timer[name] = new Date().getTime();
        }
    },
    End: function (name) {
        if (console && console.time) {
            console.timeEnd(name);
        } else {
            var result;
            if (window.performance.now) {
                result = window.performance.now() - this.Timer[name];
            } else {
                result = new Date().getTime() - this.Timer[name];
            }
            console.log(name + ": " + result);
        }
    }
}
Mx.
источник
5

Это может помочь вам.

var t0 = date.now(); doSomething(); var t1 = date.now(); console.log("Call to doSomething took approximate" + (t1 - t0)/1000 + " seconds.")

Ваджи Аслам
источник
1
Хотя этот фрагмент кода может решить вопрос, в том числе объяснение действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин, по которым вы предлагаете код. Также постарайтесь не переполнять ваш код пояснительными комментариями, это снижает удобочитаемость кода и пояснений!
Филнор
5

Вот декоратор для функций синхронизации

let timed = (f) => (...args)=>{
    let start = performance.now();
    let ret = f(...args);
    console.log(`function ${f.name} took ${(performance.now()-start).toFixed(3)}ms`)
    return ret;   
}

Применение:

let test = ()=>{/*does something*/}
test = timed(test)   // turns the function into a timed function in one line
test()               // run your code as normal, logs 'function test took 1001.900ms' 

Если вы используете асинхронные функции, вы можете сделать timedasync и добавить awaitперед f (... args), и это должно сработать. Это усложняется, если вы хотите, чтобы один декоратор обрабатывал функции синхронизации и асинхронности.

aljgom
источник
Это именно то, что я искал. Спасибо!
Эндрю Уоттерс
Есть ли способ сделать его универсальным для использования с асинхронными функциями?
Всего
4

Спасибо, Ахим Кёльнер, немного расширит ваш ответ:

var t0 = process.hrtime();
//Start of code to measure

//End of code
var timeInMilliseconds = process.hrtime(t0)[1]/1000000; // dividing by 1000000 gives milliseconds from nanoseconds

Обратите внимание, что вы не должны делать ничего, кроме того, что вы хотите измерить (например, console.log также потребуется время для выполнения и повлияет на тесты производительности).

Обратите внимание, что для того, чтобы по мере выполнения времени выполнения асинхронных функций, вы должны вставить var timeInMilliseconds = process.hrtime(t0)[1]/1000000;внутри обратного вызова. Например,

var t0 = process.hrtime();
someAsyncFunction(function(err, results) {
var timeInMilliseconds = process.hrtime(t0)[1]/1000000;

});
Андрей Марин
источник
3

Пару месяцев назад я собрал свою собственную подпрограмму, которая рассчитывает время с помощью функции Date.now () - хотя в то время принятым методом, как представляется, был performance.now () - потому что объект производительности еще не доступен (построен -in) в стабильном выпуске Node.js.

Сегодня я провел еще какое-то исследование и нашел другой метод определения времени. Так как я также нашел, как использовать это в коде Node.js, я решил поделиться этим здесь.

Следующее объединено с примерами, данными w3c и Node.js :

function functionTimer() {
    performance.mark('start')
    functionToBeTimed()
    performance.mark('end')
    performance.measure('Start to End', 'start', 'end')
    const measure = performance.getEntriesByName('Start to End')[0]
    console.log(measure.duration)
}

НОТА:

Если вы намереваетесь использовать performanceобъект в приложении Node.js, вы должны включить следующее требование: const { performance } = require('perf_hooks')

Джонатан Честин
источник
Я думаю, что вам не нужно performance.mark('end')в этом случае
kofifus
3

Есть несколько способов достижения этой цели:

  1. используя console.time

    console.time('function');
    //run the function in between these two lines for that you need to 
    //measure time taken by the function. ("ex. function();")
    console.timeEnd('function');
  2. это самый эффективный способ: использование performance.now () , например

    var v1 = performance.now();
    //run the function here for which you have top measure the time 
    var v2 = performance.now();
    console.log("total time  taken = "+(v2-v1)+"milliseconds");
  3. используйте + (добавить оператор) или getTime ()

    var h2 = +new Date(); //or
    var h2 = new Date().getTime();
    for(i=0;i<500;i++) { /* do something */}
    var h3 = +new Date();   //or 
    var h3 = new Date().getTime();
    var timeTaken = h3-h2;
    console.log("time ====", timeTaken);

Вот что происходит, когда вы применяете унарный оператор плюс к экземпляру Date: Получите значение рассматриваемого экземпляра Date. Преобразуйте его в число.

ПРИМЕЧАНИЕ: getTime()дает лучшую производительность, чем унарный + оператор.

Рохит Джайсвал
источник
1
export default class Singleton {

  static myInstance: Singleton = null;

  _timers: any = {};

  /**
   * @returns {Singleton}
   */
  static getInstance() {
    if (Singleton.myInstance == null) {
      Singleton.myInstance = new Singleton();
    }

    return this.myInstance;
  }

  initTime(label: string) {
    this._timers[label] = Date.now();
    return this._timers[label];
  }

  endTime(label: string) {
    const endTime = Date.now();
    if (this._timers[label]) {
      const delta = endTime - this._timers[label];
      const finalTime = `${label}: ${delta}ms`;
      delete this._timers[label];
      return finalTime;
    } else {
      return null;
    }
  }
}

InitTime связано с string.

return Singleton.getInstance().initTime(label); // Returns the time init

return Singleton.getInstance().endTime(label); // Returns the total time between init and end

jose920405
источник
1

Если вы хотите измерить время между несколькими вещами, которые не являются вложенными, вы можете использовать это:

function timer(lap){ 
    if(lap) console.log(`${lap} in: ${(performance.now()-timer.prev).toFixed(3)}ms`); 
    timer.prev = performance.now();
}

Аналогичен console.time (), но более прост в использовании, если вам не нужно отслеживать предыдущие таймеры.

Если вам нравится синий цвет из console.time (), вы можете использовать эту строку вместо

console.log(`${lap} in: %c${(performance.now()-timer.prev).toFixed(3)}ms`, 'color:blue');

// Usage: 
timer()              // set the start
// do something 
timer('built')       // logs 'built in: 591.815ms'
// do something
timer('copied')      // logs 'copied in: 0.065ms'
// do something
timer('compared')    // logs 'compared in: 36.41ms'
aljgom
источник
1

В моем случае я предпочитаю использовать @gramar suger и компилировать его с помощью babel.
Проблема этого метода в том, что функция должна быть внутри объекта.

Образец кода JS

function timer() {
    return (target, propertyKey, descriptor) => {
        const start = Date.now();
        let oldFunc = descriptor.value;

        descriptor.value = async function (){
            var result = await oldFunc.apply(this, arguments);
            console.log(Date.now() - start);
            return result;
        }
    }
}

// Util function 
function delay(timeout) {
    return new Promise((resolve) => setTimeout(() => {
        resolve();
    }, timeout));
}

class Test {
    @timer()
    async test(timout) {
        await delay(timout)
        console.log("delay 1");
        await delay(timout)
        console.log("delay 2");
    }
}

const t = new Test();
t.test(1000)
t.test(100)

.babelrc (для babel 6)

 {
    "plugins": [
        "transform-decorators-legacy"
    ]
 }
Ю Хуан
источник
1

Секундомер с накопительными циклами

Работает с сервером и клиентом (Node или DOM), использует Performance API. Хорошо, когда у вас много маленьких циклов, например, в функции, вызываемой 1000 раз, которая обрабатывает 1000 объектов данных, но вы хотите увидеть, как каждая операция в этой функции складывается в общую сумму.

Так что этот использует глобальный (одиночный) таймер модуля. То же самое, что и шаблон синглтона класса, чуть проще в использовании, но вы должны поместить его в отдельный, например, stopwatch.jsфайл.

const perf = typeof performance !== "undefined" ? performance : require('perf_hooks').performance;
const DIGITS = 2;

let _timers = {};

const _log = (label, delta?) => {
    if (_timers[label]) {
        console.log(`${label}: ` + (delta ? `${delta.toFixed(DIGITS)} ms last, ` : '') +
            `${_timers[label].total.toFixed(DIGITS)} ms total, ${_timers[label].cycles} cycles`);
    }
};

export const Stopwatch = {
    start(label) {
        const now = perf.now();
        if (_timers[label]) {
            if (!_timers[label].started) {
                _timers[label].started = now;
            }
        } else {
            _timers[label] = {
                started: now,
                total: 0,
                cycles: 0
            };
        }
    },
    /** Returns total elapsed milliseconds, or null if stopwatch doesn't exist. */
    stop(label, log = false) {
        const now = perf.now();
        if (_timers[label]) {
            let delta;
            if(_timers[label].started) {
                delta = now - _timers[label].started;
                _timers[label].started = null;
                _timers[label].total += delta;
                _timers[label].cycles++;
            }
            log && _log(label, delta);
            return _timers[label].total;
        } else {
            return null;
        }
    },
    /** Logs total time */
    log: _log,
    delete(label) {
        delete _timers[label];
    }
};
gombosg
источник
1

Лучший способ - использовать performance hooksмодуль. Хотя нестабильный, вы можете markконкретная области кода и между отмеченными областями.measureduration

const { performance, PerformanceObserver } = require('perf_hooks');

const measures = []

const obs = new PerformanceObserver(list => measures.push(...list.getEntries()));
obs.observe({ entryTypes: ['measure'] });
const getEntriesByType = cb => cb(measures);

const doSomething = val => {
  performance.mark('beginning of the process');

  val *= 2;

  performance.mark('after multiplication');

  performance.measure('time taken', 'beginning of the process', 'after multiplication');

  getEntriesByType(entries => {
    entries.forEach(entry => console.log(entry));
  })

  return val;
}

doSomething(4);

Попробуй здесь

toondaey
источник
0
const { performance } = require('perf_hooks');

function addUpTo(n) {
  let total = 0;
  for (let i = 1; i <= n; i++) {
    total += i;
  }
  return total;
}


let t1 = performance.now();
addUpTo(1000000000);
let t2 = performance.now();
console.log(`Time elapsed: ${(t2 - t1) / 1000} seconds`);
// Time elapsed: 1.1261566010713577 seconds
Хомам Бахрани
источник
0

С производительностью

NodeJs: требуется импортировать класс производительности

var time0 = performance.now(); // Store the time at this point into time0

yourFunction();   // The function you're measuring time for 

var time1 = performance.now(); // Store the time at this point into time1

console.log("youFunction took " + (time1 - time0) + " milliseconds to execute");

Использование console.time

console.time('someFunction');

someFunction(); // Whatever is timed goes between the two "console.time"

console.timeEnd('someFunction');
iCPSoni
источник
0
  1. Для запуска таймера используйтеconsole.time("myTimer");
  2. Необязательно: для печати прошедшего времени используйте console.timeLog("myTimer");
  3. Наконец, чтобы остановить таймер и вывести окончательное время:console.timeEnd("myTimer");

Вы можете прочитать об этом на MDN и в документации Node.js .

Доступно в Chrome, Firefox, Opera и NodeJS. (не в Edge или Internet Explorer).

bvdb
источник
-2

Как указано ранее, проверьте и используйте встроенный таймер. Но если вы хотите или должны написать свой собственный вот мои два цента:

//=-=|Source|=-=//
/**
 * JavaScript Timer Object
 *
 *      var now=timer['elapsed'](); 
 *      timer['stop']();
 *      timer['start']();
 *      timer['reset']();
 * 
 * @expose
 * @method timer
 * @return {number}
 */
timer=function(){
    var a=Date.now();
    b=0;
    return{
        /** @expose */
        elapsed:function(){return b=Date.now()-a},
        start:function(){return a=Date.now()},
        stop:function(){return Date.now()},
        reset:function(){return a=0}
    }
}();

//=-=|Google Advanced Optimized|=-=//
timer=function(){var a=Date.now();b=0;return{a:function(){return b=Date.now()-a},start:function(){return a=Date.now()},stop:function(){return Date.now()},reset:function(){return a=0}}}();

Сборник удался!

  • Оригинальный размер: 219 байт в сжатом виде (405 байт без сжатия)
  • Скомпилированный размер: 109 байт в сжатом виде (187 байт без сжатия)
  • Экономия 50,23% по сравнению с размером GZIP (53,83% без GZIP
NlaakALD
источник
-6

Принятый ответ неверен !

Поскольку JavaScript является асинхронным, значения переменной end принятого ответа будут неверными.

var start = new Date().getTime();

for (i = 0; i < 50000; ++i) {
// JavaScript is not waiting until the for is finished !!
}

var end = new Date().getTime();
var time = end - start;
alert('Execution time: ' + time); 

Выполнение for может быть очень быстрым, поэтому вы не можете видеть, что результат неправильный. Вы можете проверить это с помощью кода, выполняющего некоторый запрос:

var start = new Date().getTime();

for (i = 0; i < 50000; ++i) {
  $.ajax({
    url: 'www.oneOfYourWebsites.com',
    success: function(){
       console.log("success");
    }
  });
}

var end = new Date().getTime();
var time = end - start;
alert('Execution time: ' + time); 

Таким образом, предупреждение будет выдано очень быстро, но в консоли вы увидите, что запросы ajax продолжаются.

Вот как вы должны это сделать: https://developer.mozilla.org/en-US/docs/Web/API/Performance.now

Мирза Селимович
источник
9
Это не из-за цикла for. Цикл for будет ждать до последнего цикла, пока он не продолжит ваш исходный код. AJAX-вызовы являются асинхронными. И есть также другие функции, которые работают асинхронно. Но цикл for не выполняется асинхронно.
Scriptlabs