วิธีรับ microtime ใน Node.js


100

ฉันจะรับการประทับเวลาที่แม่นยำที่สุดใน Node.js ได้อย่างไร

ps เวอร์ชันของ Node.js ของฉันคือ 0.8.X และส่วนขยาย node-microtimeไม่ทำงานสำหรับฉัน (เกิดข้อผิดพลาดเมื่อติดตั้ง)

คำตอบ:


103

new Date().getTime()เหรอ? ซึ่งจะให้การประทับเวลาเป็นมิลลิวินาทีซึ่งเป็นค่าที่แม่นยำที่สุดที่ JS จะให้คุณ

อัปเดต: ตามที่ระบุไว้โดย vaughan process.hrtime()มีอยู่ใน Node.js - ความละเอียดคือนาโนวินาทีและสูงกว่ามาก แต่ก็ไม่ได้หมายความว่าจะต้องมีความแน่นอนมากขึ้น

PS: เพื่อให้ชัดเจนยิ่งขึ้นให้process.hrtime()ส่งคืนทูเปิลArrayที่มีเวลาจริงความละเอียดสูงในปัจจุบันเป็น [วินาทีนาโนวินาที]


91
Date.now()กรุณา.
jAndy

51
ใช้process.hrtime()
vaughan

3
ฉันต้องเห็นด้วย คำตอบนี้ผิดอย่างสิ้นเชิง ดูคำตอบด้านล่างโดย @Meryn Stol สำหรับคำตอบที่ถูกต้อง
Justin Warkentin

11
process.hrtime () เวลาเหล่านี้สัมพันธ์กับเวลาโดยพลการในอดีตและไม่เกี่ยวข้องกับเวลาของวันดังนั้นจึงไม่ขึ้นอยู่กับการหมุนของนาฬิกา การใช้งานหลักคือการวัดประสิทธิภาพระหว่างช่วงเวลา ดังนั้นจึงไม่ให้เวลาปัจจุบัน
Alex

9
คำตอบด้านบนทั้งหมดผิด process.hrtime()ไม่คืนเวลาปัจจุบัน

180

ใน 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);
Justin Warkentin

5
โปรดตรวจสอบหน่วยเวลาเมื่อแปลงวินาทีเป็นไมโครวินาที console.log (hrTime [0] * 1000000 + hrTime [1] / 1000)
itaifrenkel

ขอขอบคุณที่ชี้ให้เห็นข้อผิดพลาดนี้ itaifrenkel! ฉันได้แก้ไขรหัส Conversion แล้ว
Myrne Stol

2
ไม่ควรrequire("performance.now")จะเป็นrequire("performance-now")?
UpTheCreek

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

};

15
process.hrtime()ไม่คืนเวลาปัจจุบัน

คุณมีระบบปฏิบัติการใด
Abdennour TOUMI

คำเตือน: "micro" และ "nano" ทั้งคู่ดูเหมือนว่าจะล้น Number สำหรับผู้ที่ใช้งานได้คุณอาจต้องแปลงเป็น BigInt ก่อน
DoomGo

14

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

tl; dr

  • 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 อ่าพวกเขาทำจริง - พวกเขาเรียกมันว่า 'ส่วนขยาย'; ซึ่งทำให้ฉันพลาดสิ่งนี้ เนื่องจากผู้คนจำนวนมากมาที่บทความนี้ผ่านทางคำถามซึ่งเป็นวิธีการทำ microtime บนโหนดคำตอบก็ยังมีประโยชน์
mikemaccana

5

Node.js nanotimer

ฉันเขียน Wrapper library / object สำหรับ node.js ที่ด้านบนของการprocess.hrtimeเรียกใช้ฟังก์ชัน มีฟังก์ชั่นที่มีประโยชน์เช่นงานจับเวลาแบบซิงโครนัสและอะซิงโครนัสระบุเป็นวินาทีมิลลิวินาทีไมโครหรือแม้แต่นาโนและทำตามไวยากรณ์ของตัวจับเวลาจาวาสคริปต์ในตัวเพื่อให้คุ้นเคย

ออบเจ็กต์ตัวจับเวลายังไม่ต่อเนื่องดังนั้นคุณสามารถมีได้มากเท่าที่คุณต้องการโดยแต่ละชิ้นจะมีของตัวเองsetTimeoutหรือsetIntervalกระบวนการทำงาน

เรียกว่านาโนไทม์เมอร์ ลองดูสิ!


2

ในการทำงานด้วยความแม่นยำมากกว่าDate.now()แต่มีความแม่นยำในการลอยเป็นมิลลิวินาที:

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

2
process.hrtime () ไม่คืนเวลาปัจจุบัน
Marc J. Schmidt

คุณถูก. จากเอกสาร: "เวลาเหล่านี้สัมพันธ์กับเวลาโดยพลการในอดีตและไม่เกี่ยวข้องกับเวลาของวันดังนั้นจึงไม่ขึ้นอยู่กับการลอยตัวของนาฬิกาการใช้งานหลักคือการวัดประสิทธิภาพระหว่างช่วงเวลา" nodejs.org/api/process .html # process_process_hrtime_time
รอส

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 ค้นหา gettimeofdayNPM การโทร 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())รับการประทับเวลาเป็นมิลลิวินาที

แก้ไข:

ต่อไปนี้เป็นวิธีแก้ปัญหาที่จะมีไมโครวินาทีพร้อมลูกน้ำอย่างไรก็ตามเวอร์ชันของตัวเลขจะถูกปัดเศษโดยจาวาสคริปต์ ดังนั้นหากคุณต้องการรูปแบบเดียวกันทุกครั้งคุณควรใช้เวอร์ชัน 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


-8

ดีกว่า?

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

3
วิธีนี้ใช้ไม่ได้เลย ไม่ได้ใช้. เนื่องจากค่าเหล่านี้เป็นจำนวนเต็มองค์ประกอบที่สองของอาร์เรย์จะไม่มีความกว้างคงที่ ไม่มีเลขศูนย์นำหน้าสำหรับการรวมเป็นสตริง
user.friendly

Number (process.hrtime (). map ((n, i) => i? ('000000000' + n) .slice (-9): n) .join (''))
Mike
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.