Jak uzyskać mikrotime w Node.js?

98

Jak uzyskać najdokładniejszy znacznik czasu w Node.js?

ps Moja wersja Node.js to 0.8.X, a rozszerzenie node-microtime nie działa dla mnie (awaria podczas instalacji)

NiLL
źródło

Odpowiedzi:

102

new Date().getTime()? Daje ci to znacznik czasu w milisekundach, który jest najdokładniejszy, jaki da ci JS.

Aktualizacja: Jak stwierdził vaughan, process.hrtime()jest dostępny w Node.js - jego rozdzielczość wynosi nanosekundy, a zatem jest znacznie wyższa, co nie oznacza, że ​​musi być dokładniejsza.

PS .: Dla większej przejrzystości process.hrtime()zwraca krotkę Arrayzawierającą bieżący czas rzeczywisty w wysokiej rozdzielczości w ciągu [sekund, nanosekund]

Niet the Dark Absol
źródło
91
Date.now()Proszę.
jAndy
50
Użyjprocess.hrtime()
vaughan
3
Muszę się zgodzić. Ta odpowiedź jest całkowicie błędna. Zobacz odpowiedź @Meryn Stol, aby uzyskać poprawną odpowiedź.
Justin Warkentin
11
process.hrtime () Te czasy odnoszą się do dowolnego czasu w przeszłości i nie są związane z porą dnia, a zatem nie podlegają przesunięciom zegara. Głównym zastosowaniem jest pomiar wydajności między interwałami. Więc nie podaje aktualnego czasu
Alex
9
Wszystkie najpopularniejsze odpowiedzi są błędne. process.hrtime()nie zwraca aktualnego czasu.
178

W Node.js „czas wysokiej rozdzielczości” jest udostępniany za pośrednictwem process.hrtime. Zwraca tablicę z pierwszym elementem czas w sekundach, a drugim elementem pozostałe nanosekundy.

Aby uzyskać aktualny czas w mikrosekundach, wykonaj następujące czynności:

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

(Podziękowania dla itaifrenkel za wskazanie błędu w powyższej konwersji).

W nowoczesnych przeglądarkach czas z dokładnością do mikrosekund jest dostępny w formacie performance.now. Zobacz https://developer.mozilla.org/en-US/docs/Web/API/Performance/now, aby uzyskać dokumentację.

Zrobiłem implementację tej funkcji dla Node.js, opartą na process.hrtime, która jest stosunkowo trudna w użyciu, jeśli chcesz tylko obliczyć różnicę czasu między dwoma punktami w programie. Zobacz http://npmjs.org/package/performance-now . Zgodnie ze specyfikacją ta funkcja podaje czas w milisekundach, ale jest to liczba zmiennoprzecinkowa z dokładnością do milisekund.

W wersji 2.0 tego modułu raportowane milisekundy odnoszą się do czasu uruchomienia procesu węzła ( Date.now() - (process.uptime() * 1000)). Musisz dodać to do wyniku, jeśli chcesz mieć znacznik czasu podobny do Date.now(). Pamiętaj również, że powinieneś ponownie obliczyć Date.now() - (process.uptime() * 1000). Oba Date.nowi process.uptimesą wysoce zawodne przy precyzyjnych pomiarach.

Aby uzyskać aktualny czas w mikrosekundach, możesz użyć czegoś takiego.

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

Zobacz też: Czy JavaScript zapewnia zegar o wysokiej rozdzielczości?

Myrne Stol
źródło
27
Należy zauważyć, że aby wykonać test porównawczy, możesz przekazać wynik poprzedniego wywołania do, process.hrtime()aby uzyskać różnicę. np. var startTime = process.hrtime();a potem var diff = process.hrtime(startTime);.
Justin Warkentin
5
Sprawdź jednostki czasu podczas przeliczania sekund na mikrosekundy. console.log (hrTime [0] * 1000000 + hrTime [1] / 1000)
itaifrenkel
Dzięki za wskazanie tego błędu, itaifrenkel! Poprawiłem kod konwersji.
Myrne Stol
2
Nie powinno require("performance.now")być require("performance-now")?
UpTheCreek
5
process.hrtime()nie zwraca aktualnego czasu.
21
now('milli'); //  120335360.999686
now('micro') ; // 120335360966.583
now('nano') ; //  120335360904333

Wiadomo, że 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');
  }

};
Abdennour TOUMI
źródło
14
process.hrtime()nie zwraca aktualnego czasu.
które masz Os?
Abdennour TOUMI
12

Typ BigIntdanych jest obsługiwany od wersji Node.js 10.7.0. ( zobacz także ogłoszenie na blogu ). W przypadku tych obsługiwanych wersji Node.js process.hrtime([time])metoda jest teraz traktowana jako „starsza” i zastąpiona przez process.hrtime.bigint()metodę.

bigintWersja process.hrtime()metody powracającego aktualny wysokiej rozdzielczości w czasie rzeczywistym w A 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);

tl; dr

  • Node.js 10.7.0+ - użyj process.hrtime.bigint()
  • W przeciwnym razie - użyj process.hrtime()
d4nyll
źródło
8

Jest też https://github.com/wadey/node-microtime :

> var microtime = require('microtime')
> microtime.now()
1297448895297028
mikemaccana
źródło
OP stwierdził, że wypróbował ten pakiet i nie mógł go zainstalować.
Cameron Tacklind
@CameronTacklind Ach, rzeczywiście - nazywali to „rozszerzeniem”; co sprawiło, że tęskniłem za tym. Ponieważ wiele osób przychodzi do tego artykułu poprzez pytanie - jak zrobić mikrotime na węźle - odpowiedź jest nadal przydatna.
mikemaccana
5

Nanotimer Node.js.

Napisałem bibliotekę / obiekt opakowujący dla node.js w górnej części process.hrtimewywołania funkcji. Ma przydatne funkcje, takie jak synchroniczne i asynchroniczne zadania czasowe, określone w sekundach, milisekundach, mikro, a nawet nano, i podąża za składnią wbudowanego timera javascript, aby był znajomy.

Obiekty timera są również dyskretne, więc możesz mieć dowolną liczbę obiektów, każdy z własnym setTimeoutlub setIntervaldziałającym procesem.

Nazywa się nanotimer . Sprawdź to!

krb686
źródło
2

Aby pracować z większą precyzją niż Date.now(), ale z milisekundami z precyzją zmiennoprzecinkową:

function getTimeMSFloat() {
    var hrtime = process.hrtime();
    return ( hrtime[0] * 1000000 + hrtime[1] / 1000 ) / 1000;
}
Ross
źródło
2
process.hrtime () nie zwraca aktualnego czasu
Marc J. Schmidt
Masz rację. Z dokumentów: „Te czasy odnoszą się do dowolnego czasu w przeszłości i nie są związane z porą dnia i dlatego nie podlegają przesunięciom
Ross
1

Uzyskaj hrtimejako pojedynczy numer w jednej linii:

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

Array.reduce, gdy zostanie podany pojedynczy argument, użyje pierwszego elementu tablicy jako accumulatorwartości początkowej . Można by użyć 0jako wartości początkowej i to też by działało, ale po co robić dodatkowe * 0.

Cameron Tacklind
źródło
0

istnieją pakiety npm, które wiążą się z funkcją systemową gettimeofday (), która w systemie Linux zwraca znacznik czasu z dokładnością do mikrosekundy. Szukaj npm gettimeofday. Wywołanie C jest szybsze niżprocess.hrtime()

Andras
źródło
0

Przepisanie ułatwiające szybkie zrozumienie:

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

Źródło: https://nodejs.org/api/process.html#process_process_hrtime_time

Manohar Reddy Poreddy
źródło
0

Nie jestem zbyt dumny z tego rozwiązania, ale możesz mieć znacznik czasu w mikrosekundach lub nanosekundach w ten sposób:

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

Wiedz, że:

  • To rozwiązanie działa wyłącznie z node.js ,
  • Jest to około 3 do 10 razy wolniejsze niżDate.now()
  • Co dziwne, wydaje się to bardzo dokładne, hrTime wydaje się podążać dokładnie za taktami znacznika czasu js.
  • Możesz zamienić Date.now()na, Number(new Date())aby uzyskać sygnaturę czasową w milisekundach

Edytować:

Tutaj rozwiązanie, aby mieć mikrosekundę z przecinkiem, jednak wersja liczbowa zostanie natywnie zaokrąglona przez javascript. Więc jeśli chcesz mieć ten sam format za każdym razem, powinieneś użyć jego wersji 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
pirs
źródło
0

process.hrtime () nie podaje aktualnego ts.

To powinno działać.

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

  console.log(microSeconds / 1e3)
Saravana Kumar Chinnaraj
źródło
-8

lepszy?

Number(process.hrtime().join(''))
infinito84
źródło
3
To w ogóle nie działa. NIE UŻYWAĆ. Ponieważ te wartości są liczbami całkowitymi, drugi element tablicy nigdy nie będzie miał stałej szerokości. Nie ma wiodących zer, aby to było połączone jako ciąg.
user.friendly
Number (process.hrtime (). Map ((n, i) => i? ('000000000' + n) .slice (-9): n) .join (''))
Mike