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)

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]


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?


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');
  }

};

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()

8

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

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

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!


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;
}

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.


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()


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


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

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)

-8

lepszy?

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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.