जावास्क्रिप्ट में माइक्रोसेकंड समय


100

क्या माइक्रोसेकंड रिज़ॉल्यूशन के साथ जावास्क्रिप्ट में कोई टाइमिंग फ़ंक्शन हैं?

मैं के बारे में पता कर रहा हूँ timer.js क्रोम के लिए, और अन्य अनुकूल ब्राउज़रों, फायरफॉक्स, सफारी, ओपेरा, घोषणा, Konqueror, आदि मैं किसी भी IE के समर्थन में कोई दिलचस्पी नहीं हूँ की तरह के लिए एक समाधान हो जाएगा उम्मीद कर रहा हूँ, लेकिन जवाब सहित आईई स्वागत है।

(जेएस में मिलीसेकंड टाइमिंग की खराब सटीकता को देखते हुए, मैं इस पर अपनी सांस नहीं रोक रहा हूं!)

अपडेट: टाइमर.जेएस माइक्रोसेकंड रिज़ॉल्यूशन का विज्ञापन करता है, लेकिन यह केवल मिलीसेकंड रीडिंग को 1,000 से गुणा करता है। परीक्षण और कोड निरीक्षण द्वारा सत्यापित। निराश। [


2
आप एक ब्राउज़र में क्या करने की कोशिश कर रहे हैं जिसमें माइक्रोसेकंड सटीकता की आवश्यकता है? सामान्य तौर पर ब्राउज़रों के व्यवहार की प्रदर्शन गारंटी केवल सटीक नहीं होती है।
यूलि

4
ऐसा नहीं होगा। आप सूक्ष्म द्वितीय सटीकता पर भरोसा नहीं कर सकते भले ही वह अस्तित्व में हो। एकमात्र ठोस उपयोग का मामला जिसकी मैं कल्पना कर सकता हूं, वह क्रोम में मूल ग्राहक है, लेकिन तब आप जेएस एपीआई की परवाह नहीं करते। प्रथम श्रेणी के ब्राउज़र के रूप में "एपिफेनी" का इलाज करना और आईई को अनदेखा करना बहुत पसंद है।
रेयानोस

6
जावास्क्रिप्ट में समय को प्राप्त करने में कुछ समय लगता है, जैसा कि इसे वापस करना है- और विलंबता बढ़ जाती है यदि आप एक वेबपेज पर हैं जो घटनाओं को फिर से कर रहा है या संभाल रहा है। मैं निकटतम 10 मिलीसेकंड सटीकता पर भी भरोसा नहीं करूंगा।
kennebec

1
जैसे, कहते हैं, सुपर-उच्च गति पर पॉपअप फेंक रहे हैं? मूल रूप से, समस्या यह है कि बाहरी पार्टियों को उपयोगकर्ता मशीनों तक बहुत अधिक पहुंच प्रदान करना केवल इस तथ्य के कारण है कि एक व्यक्ति किसी वेबसाइट पर जाता है एक गंभीर समस्या है।
नुकीले

1
यह सेटइंटरवल (पॉपअप, 0) की तुलना में कोई अधिक "कमजोर" नहीं है, जो काफी तेज है कि समस्या मूल रूप से समतुल्य है। क्या मिलीसेकंड सटीकता को भी हटा दिया जाना चाहिए? kennebec: आपकी टिप्पणी समझ में आती है, धन्यवाद।
mwcz

जवाबों:


134

जैसा कि मार्क रेजन के जवाब में कहा गया है, आधुनिक ब्राउज़रों में एक एपीआई उपलब्ध है जो उप-मिलीसेकंड रिज़ॉल्यूशन टाइमिंग डेटा को स्क्रिप्ट के लिए उजागर करता है: डब्ल्यू 3 सी हाई रिज़ॉल्यूशन टाइमर , उर्फ window.performance.now()

now()Date.getTime()दो महत्वपूर्ण तरीकों से पारंपरिक से बेहतर है:

  1. now()सबमिलिसकॉन्ड रिज़ॉल्यूशन वाला एक डबल है जो पेज के नेविगेशन की शुरुआत के बाद से मिलीसेकंड की संख्या का प्रतिनिधित्व करता है। यह भिन्नात्मक में माइक्रोसेकंड की संख्या लौटाता है (जैसे 1000.123 का मान 1 सेकंड और 123 माइक्रोसेकंड है)।

  2. now()नीरस रूप से बढ़ रहा है। यह महत्वपूर्ण है क्योंकि संभवतः बाद की कॉल पर आगे या पीछे कूद Date.getTime()सकते हैं। विशेष रूप से, यदि ओएस का सिस्टम समय अपडेट किया जाता है (जैसे परमाणु घड़ी सिंक्रनाइज़ेशन), तो भी अपडेट किया जाता है। हमेशा नीरसता से बढ़ने की गारंटी है, इसलिए यह ओएस के सिस्टम समय से प्रभावित नहीं होता है - यह हमेशा दीवार-घड़ी का समय होगा (यह मानते हुए कि आपकी दीवार घड़ी परमाणु नहीं है ...)।Date.getTime()now()

now()लगभग हर जगह इस्तेमाल किया जा सकता है new Date.getTime(), + new Dateऔर Date.now()हैं। अपवाद यह है कि समय Dateऔर now()मिश्रण नहीं है, जैसा Dateकि यूनिक्स-एपोच (1970 के बाद मिलीसेकंड की संख्या) पर आधारित है , जबकि now()आपके पेज नेविगेशन शुरू होने के बाद से मिलीसेकंड की संख्या है (इसलिए यह बहुत छोटा होगा Date)।

now()Chrome स्थिर, फ़ायरफ़ॉक्स 15+ और IE10 में समर्थित है। कई पॉलीफ़िल भी उपलब्ध हैं।


1
पॉलीफ़िल्स शायद Date.now () का उपयोग कर रहे हैं, इसलिए यह अभी भी IE9 पर विचार करने का सबसे अच्छा विकल्प है और इसके लाखों उपयोगकर्ता हैं, तो तीसरे पक्ष के पुस्तकालय को क्यों मिलाते हैं
विटाली टेरेज़िव

4
मेरे दीवार घड़ी है परमाणु।
प्रोग्रामर

4
new Date.getTime()बात नहीं है। new Date().getTime()है।
कूदेस्मिथ

मुझे वास्तव में यह प्रतिक्रिया पसंद आई। मैंने कुछ परीक्षण चलाए और एक उदाहरण के साथ आया, जिसे आप अपने कंसोल में देख सकते हैं कि यह उपयोग करते समय अभी भी नाटकीय टकराव होगा। (ध्यान दें कि मैं एक अच्छी मशीन पर 10% टक्कर प्राप्त कर रहा था, यहां तक ​​कि console.logप्रत्येक रन के रूप में महंगा कुछ करने के साथ ) बाहर बनाने के लिए मुश्किल है लेकिन यहां सभी हाइलाइट किए गए कोड को कॉपी करें:last=-11; same=0; runs=100; for(let i=0;i<runs;i++) { let now = performance.now(); console.log('.'); if (now === last) { same++; } last = now; } console.log(same, 'were the same');
Bladnman

2
मेरी वर्ष 2012 की टिप्पणी पर फिर से गौर करना । performance.now () अब थोड़े थोड़े से मेलडाउन / स्पेक्टर वर्कअराउंड द्वारा फिर से तैयार किया गया है। कुछ ब्राउज़रों ने सुरक्षा कारणों से प्रदर्शन को कम कर दिया है। मुझे लगता है कि मेरी तकनीक ने कई वैध बेंचमार्किंग उपयोग-मामलों के एक बड़े सौदे के लिए कुछ प्रासंगिकता को फिर से हासिल कर लिया है, जो टाइमर-फ़ज़ सीमाओं के अधीन है। उस ने कहा, कुछ ब्राउज़रों के पास अब कुछ डेवलपर प्रदर्शन-रूपरेखा विशेषताएं / एक्सटेंशन हैं जो 2012 में मौजूद नहीं थे।
मार्क रेजन

20

अब जावास्क्रिप्ट में microseconds को मापने का एक नया तरीका है: http://gent.ilcore.com/2012/06/better-timer-for-javascript.html

हालांकि, अतीत में, मुझे मिलीसेकंड टाइमर से बाहर जावास्क्रिप्ट में 0.1 मिलीसेकंड परिशुद्धता प्राप्त करने का एक कच्चा तरीका मिला। असंभव? नहीं। पढ़ते रहिये:

मैं कुछ हाई-प्रिसिसियो प्रयोग कर रहा हूँ, जिनके लिए स्व-जाँच टाइमर की आवश्यकता होती है, और मैंने पाया कि मैं कुछ सिस्टमों पर निश्चित ब्राउज़रों के साथ 0.1 मिलीसेकंड सटीक रूप से प्राप्त करने में सक्षम था।

मैंने पाया है कि फास्ट सिस्टम पर आधुनिक GPU- त्वरित वेब ब्राउज़र में (जैसे i7 क्वाड कोर, जहां कई कोर निष्क्रिय हैं, केवल ब्राउज़र विंडो है) - मैं अब टाइमर को सटीक-सटीक होने के लिए भरोसा कर सकता हूं। वास्तव में, यह एक बेकार i7 प्रणाली पर इतना सटीक हो गया है, मैं 1,000 से अधिक प्रयासों के साथ मज़बूती से सटीक एक ही मिलीसेकंड प्राप्त करने में सक्षम हूं। केवल जब मैं एक अतिरिक्त वेब पेज, या अन्य लोड करने जैसी चीजों को करने की कोशिश कर रहा हूं, तो मिलीसेकंड सटीकता कम हो जाती है (और मैं समय से पहले जांच करने के बाद सफलतापूर्वक अपनी स्वयं की अपमानित सटीकता को पकड़ने में सक्षम हूं, यह देखने के लिए कि क्या है मेरा प्रसंस्करण समय अचानक 1 या अधिक मिलीसेकंड तक बढ़ गया - इससे मुझे अमान्य परिणामों में मदद मिलती है जो संभवतः सीपीयू के उतार-चढ़ाव से बहुत प्रभावित हुए हैं)।

यह i7 क्वाड-कोर सिस्टम (जब ब्राउज़र विंडो एकमात्र विंडो है) पर कुछ GPU त्वरित ब्राउज़र में इतना सटीक हो जाता है, कि मैंने पाया है कि मैं चाहता हूं कि मैं जावास्क्रिप्ट में 0.1ms परिशुद्धता टाइमर तक पहुंच सकता हूं, क्योंकि सटीकता आखिरकार अब है कुछ उच्च प्रकार के आला अनुप्रयोगों के लिए ऐसे टाइमर परिशुद्धता को सार्थक बनाने के लिए कुछ उच्च-अंत ब्राउज़िंग सिस्टम पर उच्च परिशुद्धता की आवश्यकता होती है, और जहां अनुप्रयोग सटीकता विचलन के लिए स्वयं-सत्यापन करने में सक्षम होते हैं।

जाहिर है यदि आप कई पास कर रहे हैं, तो आप बस कई पास (जैसे 10 पास) चला सकते हैं, फिर 0.1 मिलीसेकंड सटीक प्राप्त करने के लिए 10 से विभाजित कर सकते हैं। यह बेहतर परिशुद्धता प्राप्त करने का एक सामान्य तरीका है - कई पास करें और कुल समय को पास की संख्या से विभाजित करें।

कैसे ... अगर मैं असामान्य रूप से अद्वितीय स्थिति के कारण केवल एक विशिष्ट परीक्षा के एक बेंचमार्क पास कर सकता हूं, तो मुझे पता चला कि मैं ऐसा करके 0.1 (और कभी-कभी 0.01ms) परिशुद्धता प्राप्त कर सकता हूं:

प्रारंभ / कैलिब्रेशन:

  1. अगली मिलिसेकंड में टाइमर वृद्धि तक प्रतीक्षा करने के लिए एक व्यस्त लूप चलाएं (अगले मिलीसेकंड अंतराल की शुरुआत के लिए संरेखित टाइमर) यह व्यस्त लूप एक मिलीसेकंड से कम रहता है।
  2. टाइमर बढ़ाने के लिए इंतजार करते समय एक काउंटर को बढ़ाने के लिए एक और व्यस्त लूप चलाएं। काउंटर आपको बताता है कि एक मिलीसेकंड में कितने काउंटर बढ़े हैं। यह व्यस्त लूप एक पूर्ण मिलीसेकंड तक रहता है।
  3. उपरोक्त को दोहराएं, जब तक कि संख्याएं अल्ट्रा-स्थिर (लोडिंग समय, जेआईटी संकलक, आदि) न हो जाएं। 4. नोट: संख्या की स्थिरता आपको निष्क्रिय प्रणाली पर अपनी प्राप्य सटीकता प्रदान करती है। आप विचरण की गणना कर सकते हैं, यदि आपको सटीक जाँच करने की आवश्यकता है। कुछ ब्राउज़र पर संस्करण बड़े होते हैं, और अन्य ब्राउज़र पर छोटे होते हैं। तेज प्रणालियों पर बड़ा और धीमी प्रणालियों पर धीमा। संगति भी बदलती है। आप बता सकते हैं कि कौन से ब्राउज़र दूसरों की तुलना में अधिक सुसंगत / सटीक हैं। धीमी प्रणाली और व्यस्त सिस्टम, इनिशियलाइज़ेशन पास के बीच बड़े बदलाव का कारण बनेंगे। यह आपको एक चेतावनी संदेश प्रदर्शित करने का अवसर दे सकता है यदि ब्राउज़र आपको 0.1ms या 0.01ms माप की अनुमति देने के लिए पर्याप्त सटीकता नहीं दे रहा है। टाइमर तिरछा एक समस्या हो सकती है, लेकिन कुछ सिस्टम पर कुछ पूर्णांक मिलीसेकंड टाइमर काफी सटीक (डॉट पर काफी सही) बढ़ाते हैं, जिसके परिणामस्वरूप बहुत सुसंगत अंशांकन मूल्यों का परिणाम होगा जिस पर आप भरोसा कर सकते हैं।
  4. अंतिम काउंटर मान (या पिछले कुछ अंशांकन औसत का औसत) सहेजें

बेंचमार्किंग उप-मिलीसेकंड परिशुद्धता के लिए एक पास:

  1. अगली मिलीसेकंड तक टाइमर वेतन वृद्धि (अगले मिलीसेकंड अंतराल की शुरुआत के लिए संरेखित टाइमर) तक प्रतीक्षा करने के लिए एक व्यस्त लूप चलाएं। यह व्यस्त लूप एक मिलीसेकंड से कम रहता है।
  2. उस कार्य को निष्पादित करें जिसे आप समय पर ठीक से बेंचमार्क करना चाहते हैं।
  3. टाइमर की जाँच करें। यह आपको पूर्णांक मिलीसेकंड देता है।
  4. टाइमर में वृद्धि के लिए प्रतीक्षा करते समय एक काउंटर को बढ़ाने के लिए एक अंतिम व्यस्त लूप चलाएं। यह व्यस्त लूप एक मिलीसेकंड से कम रहता है।
  5. प्रारंभ से मूल काउंटर मान द्वारा इस काउंटर मान को विभाजित करें।
  6. अब आपको मिलीसेकंड का दशमलव भाग मिल गया है !!!!!!!!

चेतावनी: वेब ब्राउज़रों में व्यस्त छोरों की सिफारिश नहीं की जाती है, लेकिन सौभाग्य से, ये व्यस्त छोरें प्रत्येक 1 मिलीसेकंड से भी कम समय तक चलते हैं, और केवल बहुत कम बार ही चलते हैं।

जेआईटी संकलन और सीपीयू उतार-चढ़ाव जैसे चर बड़े पैमाने पर गलतियाँ जोड़ते हैं, लेकिन यदि आप कई आरंभीकरण पास चलाते हैं, तो आपके पास पूर्ण गतिशील पुनर्संयोजन होगा, और अंततः काउंटर बहुत सटीक बैठता है। सुनिश्चित करें कि सभी व्यस्त लूप सभी मामलों के लिए बिल्कुल समान कार्य है, ताकि व्यस्त लूप में अंतर के कारण अंतर न हो। सुनिश्चित करें कि परिणाम पर भरोसा करने से पहले, कोड की सभी पंक्तियों को कई बार निष्पादित किया जाता है, JIT संकलक को पहले से ही एक पूर्ण गतिशील पुनर्नवीनीकरण (dynarec) में स्थिर करने की अनुमति देने के लिए।

वास्तव में, मैंने कुछ प्रणालियों पर माइक्रोसेकंड के निकट आने वाले सटीक रूप से देखा , लेकिन मैं अभी तक इस पर भरोसा नहीं करता। लेकिन 0.1 मिलीसेकंड सटीक एक निष्क्रिय क्वाड-कोर सिस्टम पर काफी मज़बूती से काम करने के लिए प्रकट होता है, जहां मैं केवल ब्राउज़र पृष्ठ हूं। मैं एक वैज्ञानिक परीक्षण के मामले में आया था, जहाँ मैं केवल एक-ऑफ पास कर सकता था (अद्वितीय चर के कारण), और कई बार पास होने के बजाय औसत रूप से प्रत्येक पास को ठीक समय की आवश्यकता थी, इसलिए मैंने ऐसा किया।

मैंने कई प्री-पास और डमी पास (dynarec को निपटाने के लिए) किया, 0.1ms परिशुद्धता (कई सेकंड के लिए ठोस रहना) की विश्वसनीयता को सत्यापित करने के लिए, फिर अपने हाथों को कीबोर्ड / माउस से दूर रखा, जबकि बेंचमार्क ठीक नहीं हुआ, तब कई 0.1ms परिशुद्धता (फिर से ठोस रहना) की विश्वसनीयता को सत्यापित करने के लिए पोस्ट-पास। यह इस बात की भी पुष्टि करता है कि बिजली की स्थिति में परिवर्तन, या अन्य सामान, पहले और बाद के बीच नहीं हुए थे, परिणामों के साथ हस्तक्षेप। प्रत्येक एकल बेंचमार्क पास के बीच प्री-टेस्ट और पोस्ट-टेस्ट दोहराएं। इस पर, मैं काफी वस्तुतः निश्चित था कि बीच में परिणाम सटीक थे। कोई गारंटी नहीं है, लेकिन यह दिखाने के लिए जाता है कि वेब ब्राउज़र में कुछ मामलों में सटीक <0.1ms परिशुद्धता संभव है।

यह विधि केवल बहुत, बहुत आला मामलों में उपयोगी है । फिर भी, यह शाब्दिक रूप से 100% असीम रूप से गारंटीकृत नहीं होगा, आप आंतरिक और बाहरी सत्यापन की कई परतों के साथ संयुक्त होने पर काफी भरोसेमंद सटीकता और यहां तक ​​कि वैज्ञानिक सटीकता प्राप्त कर सकते हैं।


3
यह बेहतर परिशुद्धता के साथ टाइमिंग करने के लिए जटिल हुआ करता था क्योंकि हम सभी Date.now()या थे +new Date()। लेकिन अब हमारे पास है performance.now()। हालांकि यह स्पष्ट है कि आपको अधिक क्षमताओं को हैक करने के कुछ शांत तरीके मिल गए हैं, यह उत्तर अनिवार्य रूप से अप्रचलित है। इसके अलावा, व्यस्त छोरों से संबंधित किसी भी चीज की सिफारिश न करें। बस ऐसा मत करो। हमें इसकी अधिक आवश्यकता नहीं है।
स्टीवन लू

1
अधिकांश ब्राउज़रों ने अपने प्रदर्शन की सटीकता को कम कर दिया। अज्ञात () कार्यान्वयन अस्थायी रूप से कैश टाइमिंग हमले को कम करने के लिए। मुझे आश्चर्य है कि क्या इस उत्तर का अभी भी सुरक्षा अनुसंधान में महत्व है।
क्यूई फैन

2
मेरी अपनी टिप्पणी पर फिर से गौर करना। वाह, मैंने प्रदर्शन के बहुत पहले वर्ष 2012 में उपरोक्त पोस्ट किया था । ()। लेकिन अब यह थोड़े मेल्टडाउन / स्पेक्टर वर्कआर्ड्स द्वारा फिर से थोड़ा फजीहत हुई है। कुछ ब्राउज़रों ने सुरक्षा कारणों से प्रदर्शन को कम कर दिया है। मुझे लगता है कि उपरोक्त तकनीक ने कई वैध बेंचमार्किंग उपयोग-मामलों के एक बड़े सौदे के लिए कुछ प्रासंगिकता को फिर से हासिल कर लिया है, जो टाइमर-फ़ज़ सीमाओं के अधीन है।
मार्क रेजन

3

इसका उत्तर सामान्य रूप से "नहीं" है। यदि आप कुछ सर्वर-साइड वातावरण में जावास्क्रिप्ट का उपयोग कर रहे हैं (जो कि ब्राउज़र में नहीं है), तो सभी दांव बंद हैं और आप कुछ भी करने की कोशिश कर सकते हैं।

संपादित करें - यह उत्तर पुराना है; मानकों की प्रगति हुई है और सटीक समय की समस्या के समाधान के रूप में नई सुविधाएं उपलब्ध हैं। फिर भी, यह याद रखना चाहिए कि एक वास्तविक रीयल-टाइम ऑपरेटिंग सिस्टम के डोमेन के बाहर, साधारण गैर-विशेषाधिकार प्राप्त कोड का संसाधनों की गणना करने के लिए इसकी पहुंच पर सीमित नियंत्रण है। प्रदर्शन को मापना वैसा नहीं है (आवश्यक) प्रदर्शन की भविष्यवाणी के रूप में ।


2

यहाँ के लिए मेरे उच्च संकल्प टाइमर दिखा एक उदाहरण है Node.js :

 function startTimer() {
   const time = process.hrtime();
   return time;
 }

 function endTimer(time) {
   function roundTo(decimalPlaces, numberToRound) {
     return +(Math.round(numberToRound + `e+${decimalPlaces}`)  + `e-${decimalPlaces}`);
   }
   const diff = process.hrtime(time);
   const NS_PER_SEC = 1e9;
   const result = (diff[0] * NS_PER_SEC + diff[1]); // Result in Nanoseconds
   const elapsed = result * 0.0000010;
   return roundTo(6, elapsed); // Result in milliseconds
 }

उपयोग:

 const start = startTimer();

 console.log('test');

 console.log(`Time since start: ${endTimer(start)} ms`);

आम तौर पर, आप उपयोग करने में सक्षम हो सकते हैं:

 console.time('Time since start');

 console.log('test');

 console.timeEnd('Time since start');

यदि आप कोड के समय खंड हैं जिसमें लूपिंग शामिल है, तो आप console.timeEnd()अपने टाइमर परिणामों को एक साथ जोड़ने के लिए मूल्य तक पहुंच प्राप्त नहीं कर सकते हैं। आप कर सकते हैं, लेकिन यह बुरा हो जाता है क्योंकि आपको अपने चलने वाले चर के मान को इंजेक्ट करना होगा, जैसे कि i, और यह पता लगाने के लिए एक शर्त सेट करें कि क्या लूप किया जाता है।

यहाँ एक उदाहरण है क्योंकि यह उपयोगी हो सकता है:

 const num = 10;

 console.time(`Time til ${num}`);

 for (let i = 0; i < num; i++) {
   console.log('test');
   if ((i+1) === num) { console.timeEnd(`Time til ${num}`); }
   console.log('...additional steps');
 }

उद्धृत करें: https://nodejs.org/api/process.html#process_process_hrtime_time

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.