Як отримати мікрочас у Node.js?


98

Як я можу отримати найточнішу позначку часу в Node.js?

ps Моя версія Node.js - 0.8.X, і розширення node-microtime для мене не працює (збій при установці)

Відповіді:


102

new Date().getTime()? Це дає вам мітку часу в мілісекундах, яка є найбільш точною, яку вам дасть JS.

Оновлення: Як заявив vaughan, process.hrtime()доступний у Node.js - його роздільна здатність становить наносекунди, а отже набагато вища, також це не означає, що він повинен бути точнішим.

PS: Щоб бути зрозумілішим, process.hrtime()повертає вам кортеж, Arrayщо містить поточний реальний час із високою роздільною здатністю за [секунди, наносекунди]


91
Date.now()будь ласка.
jAndy

48
Використанняprocess.hrtime()
vaughan

2
Я повинен погодитися. Ця відповідь абсолютно помилкова. Дивіться нижче відповідь @Meryn Stol для правильної відповіді.
Джастін Варкентін,

11
process.hrtime () Ці часи відносяться до довільного часу в минулому і не пов'язані з часом доби, а тому не піддаються зміщенню годинника. Основне використання - для вимірювання продуктивності між інтервалами. Тож це не дає поточного часу
Олексій

9
Усі основні відповіді помилкові. process.hrtime()не повертає поточний час.

175

У Node.js "час з високою роздільною здатністю" стає доступним через process.hrtime. Він повертає масив з першим елементом, що протікає в секундах, а другий елемент - залишковими наносекундами.

Щоб отримати поточний час у мікросекундах, виконайте наступне:

var hrTime = process.hrtime()
console.log(hrTime[0] * 1000000 + hrTime[1] / 1000)

(Дякуємо itaifrenkel за те, що вказав на помилку у перетворенні вище.)

У сучасних браузерах час з мікросекундною точністю доступний як performance.now. Див. Https://developer.mozilla.org/en-US/docs/Web/API/Performance/now для отримання документації.

Я здійснив реалізацію цієї функції для Node.js на основі process.hrtime, яку порівняно важко використовувати, якщо ви лише хочете обчислити різницю в часі між двома точками в програмі. Див. Http://npmjs.org/package/performance-now . За специфікацією ця функція повідомляє час у мілісекундах, але це плаваюча з точністю до мілісекунд.

У версії 2.0 цього модуля повідомлені мілісекунди відносно часу запуску процесу вузла ( Date.now() - (process.uptime() * 1000)). Вам потрібно додати це до результату, якщо ви хочете позначку часу, подібну до Date.now(). Також зауважте, що вам слід повторно обчислити Date.now() - (process.uptime() * 1000). Обидва Date.nowі process.uptimeдуже ненадійні для точних вимірювань.

Щоб отримати поточний час у мікросекундах, ви можете використати щось подібне.

var loadTimeInMS = Date.now()
var performanceNow = require("performance-now")
console.log((loadTimeInMS + performanceNow()) * 1000)

Дивіться також: Чи надає JavaScript таймер із високою роздільною здатністю?


27
Слід зазначити, що для виконання тесту ви можете передати результат попереднього дзвінка, process.hrtime()щоб отримати різницю. наприклад, var startTime = process.hrtime();а потім var diff = process.hrtime(startTime);.
Джастін Варкентін

5
Будь ласка, перевірте одиниці часу при перетворенні секунд у мікросекунди. console.log (hrTime [0] * 1000000 + hrTime [1] / 1000)
itaifrenkel

Дякуємо, що вказали на цю помилку, itaifrenkel! Я виправив код перетворення.
Myrne Stol

2
Не повинно require("performance.now")бути require("performance-now")?
UpTheCreek

5
process.hrtime()не повертає поточний час.

21
now('milli'); //  120335360.999686
now('micro') ; // 120335360966.583
now('nano') ; //  120335360904333

Відомо, що nowце:

const now = (unit) => {

  const hrTime = process.hrtime();

  switch (unit) {

    case 'milli':
      return hrTime[0] * 1000 + hrTime[1] / 1000000;

    case 'micro':
      return hrTime[0] * 1000000 + hrTime[1] / 1000;

    case 'nano':
      return hrTime[0] * 1000000000 + hrTime[1];

    default:
      return now('nano');
  }

};

14
process.hrtime()не повертає поточний час.

які ОС у вас є?
Абденнур ТУМІ

11

Тип BigIntданих підтримується з Node.js 10.7.0. ( див. також оголошення в блозі ). Для цих підтримуваних версій Node.js process.hrtime([time])метод тепер розглядається як «застарілий», замінений process.hrtime.bigint()методом.

bigintВерсія process.hrtime()методи повернення поточного високого дозволу в реальному часі в bigint.

const start = process.hrtime.bigint();
// 191051479007711n

setTimeout(() => {
  const end = process.hrtime.bigint();
  // 191052633396993n

  console.log(`Benchmark took ${end - start} nanoseconds`);
  // Benchmark took 1154389282 nanoseconds
}, 1000);

тл; д-р

  • Node.js 10.7.0+ - Використовуйте process.hrtime.bigint()
  • В іншому випадку - Використовуйте process.hrtime()

8

Також є https://github.com/wadey/node-microtime :

> var microtime = require('microtime')
> microtime.now()
1297448895297028

OP заявив, що вони спробували цей пакет і не змогли встановити його.
Cameron Tacklind,

@CameronTacklind Ах, справді - вони назвали це "розширенням"; що змусило мене скучити за цим. Оскільки багато людей приходять до цієї статті через питання - а як це зробити мікрочас на вузлі - відповідь все ще корисна.
mikemaccana

5

Node.js нанотимер

Я написав обгорткову бібліотеку / об'єкт для node.js поверх process.hrtimeвиклику функції. Він має корисні функції, такі як синхронізація синхронних та асинхронних завдань, що визначаються в секундах, мілісекундах, мікро- або навіть нано, і слідує синтаксису вбудованого таймера JavaScript, щоб бути знайомим.

Об'єкти таймера також дискретно, так що ви можете мати стільки , скільки ви хочете, кожен зі своїм власним setTimeoutабо setIntervalпроцесом , запущеним.

Це називається нанотимер . Перевір!


2

Щоб працювати з більшою точністю, ніж Date.now(), але з мілісекундами точності плавання:

function getTimeMSFloat() {
    var hrtime = process.hrtime();
    return ( hrtime[0] * 1000000 + hrtime[1] / 1000 ) / 1000;
}

2
process.hrtime () не повертає поточний час
Марк Дж. Шмідт,

Ти маєш рацію. З документації: "Ці часи відносяться до довільного часу в минулому, і не пов'язані з часом доби і, отже, не піддаються зміщенню
Росс,

1

Отримайте hrtimeяк одне число в одному рядку:

const begin = process.hrtime();
// ... Do the thing you want to measure
const nanoSeconds = process.hrtime(begin).reduce((sec, nano) => sec * 1e9 + nano)

Array.reduce, коли дається один аргумент, буде використовувати перший елемент масиву як початкове accumulatorзначення. Можна використовувати 0як початкове значення, і це теж спрацювало б, але навіщо робити додаткове * 0.


0

є пакети npm, які прив'язуються до системної функції gettimeofday (), яка повертає мікросекундну мітку часу точності в Linux. Шукати npm gettimeofday. Виклик C швидший, ніжprocess.hrtime()


0

Перепишіть, щоб допомогти швидше зрозуміти:

const hrtime = process.hrtime();     // [0] is seconds, [1] is nanoseconds

let nanoSeconds = (hrtime[0] * 1e9) + hrtime[1];    // 1 second is 1e9 nano seconds
console.log('nanoSeconds:  ' + nanoSeconds);
//nanoSeconds:  97760957504895

let microSeconds = parseInt(((hrtime[0] * 1e6) + (hrtime[1]) * 1e-3));
console.log('microSeconds: ' + microSeconds);
//microSeconds: 97760957504

let milliSeconds = parseInt(((hrtime[0] * 1e3) + (hrtime[1]) * 1e-6));
console.log('milliSeconds: ' + milliSeconds);
//milliSeconds: 97760957

Джерело: https://nodejs.org/api/process.html#process_process_hrtime_time


0

Я не так пишаюся цим рішенням, але ви можете мати позначку часу в мікросекундах або наносекундах таким чином:

const microsecond = () => Number(Date.now() + String(process.hrtime()[1]).slice(3,6))
const nanosecond = () => Number(Date.now() + String(process.hrtime()[1]).slice(3))

// usage
microsecond() // return 1586878008997591
nanosecond()  // return 1586878009000645600

// Benchmark with 100 000 iterations
// Date.now: 7.758ms
// microsecond: 33.382ms
// nanosecond: 31.252ms

Знаю, що:

  • Це рішення працює виключно з node.js ,
  • Це приблизно в 3-10 разів повільніше, ніжDate.now()
  • Як не дивно, це здається дуже точним, здається, hrTime точно відповідає позначкам часової відмітки js.
  • Ви можете замінити Date.now(), Number(new Date())щоб отримати мітку часу в мілісекундах

Редагувати:

Тут є рішення мати мікросекунду з комою, однак числова версія буде округлена спочатку за допомогою JavaScript. Отже, якщо ви хочете щоразу мати однаковий формат, вам слід використовувати його String-версію.

const microsecondWithCommaString = () => (Date.now() + '.' + String(process.hrtime()[1]).slice(3,7))
const microsecondWithComma = () => Number(Date.now() + '.' + String(process.hrtime()[1]).slice(3,7))

microsecondWithCommaString() // return "1586883629984.8997"
microsecondWithComma() // return 1586883629985.966

0

process.hrtime () не дає поточного ts.

Це має спрацювати.

 const loadNs       = process.hrtime(),
        loadMs       = new Date().getTime(),
        diffNs       = process.hrtime(loadNs),
        microSeconds = (loadMs * 1e6) + (diffNs[0] * 1e9) + diffNs[1]

  console.log(microSeconds / 1e3)

-8

краще?

Number(process.hrtime().join(''))

3
Це взагалі не працює. НЕ ВИКОРИСТОВУВАТИ. Оскільки ці значення є цілими числами, другий елемент масиву ніколи не матиме фіксованої ширини. Немає провідних нулів, щоб це можна було об’єднати як рядок.
user.friendly

Номер (process.hrtime (). Map ((n, i) => i? ('000000000' + n) .slice (-9): n) .join (''))
Майк,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.