हॉट पथों के लिए CPU प्रोफ़ाइल और फ़्लेम ग्राफ़
CPU प्रोफ़ाइल रिकॉर्ड कीजिए और सबसे अधिक समय लेने वाले फ़ंक्शन खोजने के लिए फ़्लेम ग्राफ़ पढ़िए।
हॉट पथों के लिए CPU प्रोफ़ाइल और फ़्लेम ग्राफ़, CoddyKit पर Node.js बैकएंड विकास बूटकैंप का एक निःशुल्क पाठ है। यह 4 में से 3वाँ पाठ है। आप नीचे पूरा पाठ निःशुल्क पढ़ सकते हैं—फिर अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर के साथ ब्राउज़र में इसका व्यावहारिक अभ्यास कर सकते हैं। यह Node.js बैकएंड विकास बूटकैंप सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। Node.js बैकएंड विकास बूटकैंप पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
CPU प्रोफाइलिंग क्यों महत्वपूर्ण है
जब Node.js बैकएंड धीमा लगता है, तो कारण आम तौर पर दो में से एक होता है: प्रक्रिया प्रतीक्षा कर रही है (I/O, डेटाबेस, नेटवर्क) या वह गणना कर रही है (एकल मुख्य थ्रेड पर CPU का उपयोग)। CPU प्रोफ़ाइल बताती है कि दूसरी स्थिति में समय ठीक कहाँ जा रहा है।
- यह एक निश्चित आवृत्ति पर कॉल स्टैक के नमूने लेती है (V8 लगभग 1000 Hz का उपयोग करता है, यानी प्रति मिलीसेकंड एक नमूना)।
- प्रत्येक नमूना उस समय चल रहे फ़ंक्शन और उसे कॉल करने वाले पूरे स्टैक को दर्ज करता है।
- जो फ़ंक्शन कई नमूनों में दिखाई देते हैं, वे आपके हॉट पथ हैं — इन्हीं को बेहतर बनाना उपयोगी होगा।
Node.js JavaScript को एक ही थ्रेड पर चलाता है, इसलिए एक अकेला हॉट फ़ंक्शन आने वाले हर अनुरोध को रोक सकता है। प्रोफाइलिंग अनुमान लगाने के बजाय उसे खोज निकालती है।
स्वयं का समय बनाम कुल समय
हर प्रोफाइलर प्रत्येक फ़ंक्शन के लिए दो संख्याएँ अलग-अलग दिखाता है, और इन्हें भ्रमित करना प्रोफाइलिंग की सबसे सामान्य गलती है।
- स्वयं का समय (जिसे एक्सक्लूसिव भी कहते हैं): फ़ंक्शन के अपने बॉडी को चलाने में लगा समय, उसके द्वारा कॉल किए गए चाइल्ड फ़ंक्शन के समय को छोड़कर।
- कुल समय (जिसे इनक्लूसिव भी कहते हैं): स्वयं का समय और कॉल किए गए फ़ंक्शन के अंदर लगा पूरा समय।
कुल समय में ऊपर रहने वाला फ़ंक्शन केवल ऐसा समन्वयक हो सकता है जो महँगे चाइल्ड फ़ंक्शन कॉल करता है। स्वयं के समय में ऊपर रहने वाला फ़ंक्शन वह है जहाँ CPU वास्तव में खर्च हो रहा है। पहले स्वयं के समय के आधार पर अनुकूलन करें।
CLI से प्रोफ़ाइल रिकॉर्ड करना
किसी स्क्रिप्ट की प्रोफ़ाइल पाने का सबसे तेज़ तरीका अंतर्निहित V8 फ़्लैग है। न अतिरिक्त पैकेज चाहिए, न कोड में बदलाव।
node --prof app.jsएक कच्चीisolate-*.logफ़ाइल लिखता है।node --prof-process isolate-*.log > profile.txtइसे टिक-विभाजन वाले मनुष्य-पठनीय सारांश में बदल देता है।
सारांश टिक को JavaScript, C++ और GC के आधार पर समूहित करता है और सबसे अधिक समय लेने वाले फ़ंक्शन सूचीबद्ध करता है। यह केवल पाठ के रूप में होता है, इसलिए दृश्य फ़्लेम ग्राफ़ के लिए हम आगे इंस्पेक्टर प्रोटोकॉल का उपयोग करेंगे। नीचे CPU-आधारित कार्यभार दिया गया है, जिसकी आप इस तरीके से प्रोफ़ाइल बना सकते हैं।
function isPrime(n) {
if (n < 2) return false;
for (let i = 2; i * i <= n; i++) {
if (n % i === 0) return false;
}
return true;
}
function countPrimes(limit) {
let count = 0;
for (let n = 0; n < limit; n++) {
if (isPrime(n)) count++;
}
return count;
}
console.log(countPrimes(2_000_000));इंस्पेक्टर के माध्यम से प्रोग्राम से रिकॉर्ड करना
लंबे समय तक चलने वाले सर्वर के लिए आप अक्सर किसी विशेष समयावधि की प्रोफ़ाइल बनाना चाहते हैं। अंतर्निहित inspector मॉड्यूल आपको अपने कोड के भीतर से V8 CPU प्रोफाइलर शुरू और बंद करने तथा .cpuprofile फ़ाइल में सहेजने देता है।
- एक
Sessionखोलें, उससे कनेक्ट करें औरProfilerडोमेन को सक्षम करें। Profiler.startकॉल करें, कार्यभार चलाएँ, फिरProfiler.stopकॉल करें।- लौटाई गई प्रोफ़ाइल JSON होती है, जिसे आप डिस्क पर लिखकर Chrome DevTools या VS Code में लोड कर सकते हैं।
const inspector = require('node:inspector');
const fs = require('node:fs');
const session = new inspector.Session();
session.connect();
function work() {
let sum = 0;
for (let i = 0; i < 5e7; i++) sum += Math.sqrt(i);
return sum;
}
session.post('Profiler.enable', () => {
session.post('Profiler.start', () => {
work();
session.post('Profiler.stop', (err, { profile }) => {
fs.writeFileSync('./work.cpuprofile', JSON.stringify(profile));
console.log('Saved work.cpuprofile');
session.disconnect();
});
});
});फ़्लेम ग्राफ़ वास्तव में क्या दिखाता है
फ्लेम ग्राफ स्टैक नमूनों को एक चित्र में बदल देता है। इसे इस तरह पढ़ें:
- x-अक्ष समय नहीं है — यह स्टैक्स का समूह है। चौड़ाई = उस फ़्रेम वाले नमूनों की संख्या, यानी उसने कितना CPU इस्तेमाल किया।
- y-अक्ष स्टैक की गहराई है। सबसे नीचे का फ़्रेम कॉल करने वाला है; उसके ऊपर रखे फ़्रेम उसके द्वारा बुलाए गए फ़ंक्शन हैं।
- चौड़े फ़्रेम का अर्थ है कि किसी फ़ंक्शन (और उसके चाइल्ड फ़ंक्शन) ने बहुत CPU इस्तेमाल किया। ऊपर की ओर मौजूद चौड़े फ़्रेम, जिनके ऊपर बहुत कम फ़्रेम हों, असली काम करने वाले लीफ़ फ़्रेम होते हैं।
रंग आमतौर पर यादृच्छिक होते हैं और उनका कोई अर्थ नहीं होता — उनके आधार पर निष्कर्ष न निकालें। आपको सबसे चौड़े समतल हिस्से खोजने हैं, सबसे ऊँचे टावर नहीं।
फ्लेम ग्राफ बनाम फ्लेम चार्ट
ये दोनों एक जैसे दिखते हैं, लेकिन अलग-अलग सवालों के जवाब देते हैं, और Chrome DevTools दोनों दिखाता है।
- फ्लेम चार्ट (DevTools "Performance" टाइमलाइन): x-अक्ष बाएँ से दाएँ बीता हुआ वास्तविक समय दिखाता है। यह यह देखने के लिए उपयोगी है कि कुछ कब हुआ और घटनाएँ किस क्रम में हुईं।
- फ्लेम ग्राफ (एकत्रित): एक जैसे फ़्रेम मिलाए जाते हैं और चौड़ाई के अनुसार क्रमबद्ध किए जाते हैं। यह देखने के लिए उपयोगी है कि पूरे रन के दौरान कौन-सा फ़ंक्शन सबसे अधिक CPU इस्तेमाल कर रहा था, चाहे वह कब चला हो।
हॉट पाथ खोजने के लिए आपको एकत्रित फ्लेम ग्राफ चाहिए: अलग-अलग समय पर 10,000 बार बुलाया गया फ़ंक्शन 10,000 अदृश्य पतली पट्टियों के बजाय एक मोटी पट्टी के रूप में दिखाई देता है।
0x से फ्लेम ग्राफ बनाना
0x टूल आपकी प्रक्रिया को अपने आवरण में चलाता है, प्रोफ़ाइल कैप्चर करता है और एक ही चरण में इंटरैक्टिव HTML फ्लेम ग्राफ बनाता है — Node.js सेवाओं के लिए यह आदर्श है।
npx 0x app.jsऐप चलाता है और बाहर निकलने पर ब्राउज़र में फ्लेम ग्राफ खोलता है।- सर्वर के लिए,
0xके रिकॉर्ड करने के दौरान उस पर लोड डालें (उदाहरण के लिएautocannonसे), फिर ग्राफ बनाने के लिए प्रक्रिया रोक दें।
0x व्यूअर में आप ज़ूम करने के लिए किसी भी फ़्रेम पर क्लिक कर सकते हैं और नाम से खोजकर उन सभी स्थानों को हाइलाइट कर सकते हैं जहाँ कोई फ़ंक्शन दिखाई देता है। नीचे एक छोटा HTTP सर्वर है, जिसकी लोड के तहत प्रोफ़ाइल बनाना उपयोगी होगा।
const http = require('node:http');
function renderRow(i) {
return '<tr><td>' + i + '</td><td>' + (i * i) + '</td></tr>';
}
http.createServer((req, res) => {
let html = '<table>';
for (let i = 0; i < 5000; i++) {
html += renderRow(i);
}
html += '</table>';
res.setHeader('Content-Type', 'text/html');
res.end(html);
}).listen(3000, () => console.log('listening on 3000'));ग्राफ पढ़ना: सबसे चौड़ा लीफ़ खोजें
किसी भी फ्लेम ग्राफ में हॉट पाथ खोजने का व्यवस्थित तरीका:
- ग्राफ के ऊपरी किनारे को स्कैन करें (लीफ़ फ़्रेम)। नमूने लिए जाने के समय वास्तव में चल रहे फ़ंक्शन यही होते हैं।
- सबसे चौड़े लीफ़ या समतल हिस्से को खोजें। यह एकल फ़्रेम आपके सेल्फ़ टाइम का सबसे बड़ा हिस्सा है।
- वहाँ से नीचे की ओर जाएँ और वहाँ तक पहुँचने वाली कॉल चेन समझें — इससे पता चलता है कि आपको किसे बदलना चाहिए।
फ़्रेमवर्क के शोर से सावधान रहें: (anonymous), module.exports या रनटाइम के आंतरिक फ़्रेम अक्सर चौड़े होते हैं, क्योंकि सब कुछ उनके माध्यम से गुजरता है। चौड़े ऑर्केस्ट्रेटर फ़्रेमों को अनदेखा करें और चौड़े लीफ़ फ़्रेमों पर ध्यान दें।
गार्बेज कलेक्शन का दबाव पहचानना
फ्लेम ग्राफ केवल आपका कोड नहीं दिखाते — वे V8 रनटाइम को भी सामने लाते हैं। यदि आपको GC, Scavenge या Mark-Compact जैसे नाम वाले चौड़े फ़्रेम दिखाई दें, तो CPU लॉजिक चलाने के बजाय गार्बेज कलेक्शन में खर्च हो रहा है।
- GC की अधिक चौड़ाई का आमतौर पर अर्थ है कि आप हॉट पाथ में बहुत अधिक अल्पकालिक ऑब्जेक्ट बना रहे हैं (लूप में स्ट्रिंग जोड़ना, हर अनुरोध पर क्लोज़र या ऐरे बनाना)।
- इसका समाधान शायद ही कभी "फ़ंक्शन को ऑप्टिमाइज़ करना" होता है — समाधान है "कम ऑब्जेक्ट बनाना": बफ़र का पुनः उपयोग करें, ऐरे पहले से तैयार करें और हर पुनरावृत्ति में ऑब्जेक्ट लिटरल बनाने से बचें।
नीचे दिया गया उदाहरण हर पुनरावृत्ति में नया ऑब्जेक्ट बनाता है — यह वह सामान्य पैटर्न है जो GC फ़्रेमों को प्रमुख बना देता है।
function process(n) {
const results = [];
for (let i = 0; i < n; i++) {
// a new object every iteration -> GC pressure
results.push({ id: i, squared: i * i, label: 'item-' + i });
}
let sum = 0;
for (const r of results) sum += r.squared;
return sum;
}
console.log(process(1_000_000));डीऑप्टिमाइज़ेशन और इनलाइनिंग के संकेत
V8 हॉट फ़ंक्शन को ऑप्टिमाइज़ किए गए मशीन कोड में कंपाइल करता है। जब किसी फ़ंक्शन को वापस धीमे बाइटकोड पर जाना पड़ता है, तो वह डीऑप्टिमाइज़ हो जाता है और प्रोफ़ाइल में अप्रत्याशित रूप से चौड़े फ़्रेम दिखाई देते हैं।
node --trace-deopt app.jsके साथ चलाने पर हर डीऑप्टिमाइज़ेशन और उसका कारण लॉग होता है (जैसे ऑब्जेक्ट का आकार बदलना या ऐरे में अलग-अलग प्रकार मिलाना)।node --trace-opt app.jsदिखाता है कि कौन-से फ़ंक्शन ऑप्टिमाइज़ हुए।- फ़ंक्शन आर्ग्युमेंट्स को मोनोमॉर्फ़िक रखने से (हमेशा एक ही आकार/प्रकार) V8 उन्हें ऑप्टिमाइज़ और इनलाइन बनाए रख सकता है।
नीचे दिया गया फ़ंक्शन तेज़ रहता है क्योंकि उसे हमेशा संख्याएँ मिलती हैं; उसे स्ट्रिंग देने पर डीऑप्टिमाइज़ेशन होगा और प्रोफ़ाइल में फ़्रेम अधिक चौड़ा दिखाई देगा।
function add(a, b) {
return a + b;
}
let total = 0;
for (let i = 0; i < 1e7; i++) {
total = add(total, i); // monomorphic: always numbers, stays optimized
}
console.log(total);बार-बार अपनाया जा सकने वाला प्रोफ़ाइलिंग कार्यप्रवाह
इन सभी चरणों को एक ऐसे चक्र में जोड़ें जिसे आप किसी भी बैकएंड पर चला सकें:
- लोड को नियत रूप से दोहराएँ (बेंचमार्क या दोबारा चलाए गए ट्रैफ़िक से), ताकि दो प्रोफ़ाइलों की तुलना की जा सके।
- प्रोफ़ाइल रिकॉर्ड करें (
--prof,inspectorसत्र या0xसे)। - फ्लेम ग्राफ पढ़ें: सबसे चौड़ा लीफ़ फ़्रेम = सबसे अधिक सेल्फ़ टाइम = पहला लक्ष्य।
- ठीक उसी फ़ंक्शन को सुधारें, और कुछ न बदलें।
- उसी लोड के तहत फिर से प्रोफ़ाइल बनाएँ और पुष्टि करें कि मोटी पट्टी छोटी हो गई है।
हर पुनरावृत्ति में केवल एक चीज़ बदलें। यदि आप एक साथ तीन फ़ंक्शन ठीक करते हैं, तो पता नहीं चलेगा कि किस बदलाव से लाभ हुआ — और उनमें से किसी एक ने स्थिति खराब भी की हो सकती है।
त्वरित जाँच: ग्राफ पढ़ना
आपने एक धीमे एंडपॉइंट की प्रोफ़ाइल बनाई। एकत्रित फ्लेम ग्राफ में आपका अनुरोध हैंडलर सबसे चौड़ा फ़्रेम है, लेकिन उसके ऊपर चाइल्ड फ़्रेमों के लंबे स्टैक हैं। ऊपर के पास मौजूद एक छोटा लीफ़ फ़्रेम, JSON.stringify, भी बहुत चौड़ा है। आपको सबसे पहले किस फ़ंक्शन को ऑप्टिमाइज़ करना चाहिए?
पुनरावलोकन
अब आप Node.js बैकएंड में CPU के हॉट पाथ खोज और ठीक कर सकते हैं:
- सेल्फ़ टाइम (एक्सक्लूसिव) वह समय है जहाँ CPU काम करता है; कुल समय (इन्क्लूसिव) में चाइल्ड फ़ंक्शन भी शामिल होते हैं। सेल्फ़ टाइम के आधार पर ऑप्टिमाइज़ करें।
- इंटरैक्टिव फ्लेम ग्राफ के लिए
node --prof, बिल्ट-इनinspectorसत्र या0xसे रिकॉर्ड करें। - फ्लेम ग्राफ में x-अक्ष नमूनों की संख्या (CPU) है, समय नहीं, और y-अक्ष स्टैक की गहराई है। सबसे चौड़े लीफ़ फ़्रेम को खोजें।
- चौड़े
GC/Scavengeफ़्रेम ऑब्जेक्ट बनाने के दबाव का संकेत हैं — लॉजिक को सूक्ष्म रूप से ऑप्टिमाइज़ करने के बजाय कम ऑब्जेक्ट बनाएँ। - पॉलीमॉर्फ़िक और आकार बदलने वाले कोड से होने वाले डीऑप्टिमाइज़ेशन पकड़ने के लिए
--trace-deoptइस्तेमाल करें। - चक्र अपनाएँ: दोहराएँ, रिकॉर्ड करें, पढ़ें, एक चीज़ ठीक करें और फिर से प्रोफ़ाइल बनाएँ।
एआई शिक्षक के साथ JavaScript सीखें — निःशुल्क
अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।
- पाठ्यक्रम
- 22
- पाठ
- 92
अक्सर पूछे जाने वाले प्रश्न
क्या “हॉट पथों के लिए CPU प्रोफ़ाइल और फ़्लेम ग्राफ़” पाठ निःशुल्क है?
हाँ—“हॉट पथों के लिए CPU प्रोफ़ाइल और फ़्लेम ग्राफ़” का पूरा पाठ यहाँ वेब पर निःशुल्क पढ़ा जा सकता है। इंटरैक्टिव अभ्यास (अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर) करने और Node.js बैकएंड विकास बूटकैंप पाठ्यक्रम का बाकी हिस्सा अनलॉक करने के लिए CoddyKit PRO लें। Node.js बैकएंड विकास बूटकैंप पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
“हॉट पथों के लिए CPU प्रोफ़ाइल और फ़्लेम ग्राफ़” में मैं क्या सीखूँगा?
CPU प्रोफ़ाइल रिकॉर्ड कीजिए और सबसे अधिक समय लेने वाले फ़ंक्शन खोजने के लिए फ़्लेम ग्राफ़ पढ़िए। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ Node.js बैकएंड विकास बूटकैंप का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।
क्या Node.js बैकएंड विकास बूटकैंप शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?
पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर Node.js बैकएंड विकास बूटकैंप शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 3वाँ पाठ है।
“हॉट पथों के लिए CPU प्रोफ़ाइल और फ़्लेम ग्राफ़” पाठ पूरा करने में कितना समय लगता है?
CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।
क्या मैं इस Node.js बैकएंड विकास बूटकैंप पाठ में कोड लिख और चला सकता हूँ?
हाँ। हर Node.js बैकएंड विकास बूटकैंप पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।
इस पाठ्यक्रम के सभी पाठ
- V8 हीप, जनरेशनल GC और ऑब्जेक्ट का जीवनकाल
- हीप स्नैपशॉट कैप्चर और तुलना
- हॉट पथों के लिए CPU प्रोफ़ाइल और फ़्लेम ग्राफ़
- सामान्य लीक पैटर्न का पता लगाना और समाधान