Mundarija (24)
- Bu darsda
- 1. Nega bu kerak?
- 2. --cpu-prof: profil yig'ish
- 2.1 Tajriba dasturi
- 2.2 Profil
- 2.3 .cpuprofile ichida nima bor
- 3. Haqiqiy profil va inlining tuzog'i
- 3.1 Funksiyalar bo'yicha
- 3.2 Qatorlar bo'yicha
- 3.3 Tuzatish va qayta o'lchash
- 4. Flamegraph va flame chart
- 5. Boshqa vositalar
- 5.1 --prof va --prof-process
- 5.2 0x va boshqalar
- 6. CLI qadami: valyuta tahlil profili
- 7. Ko'p uchraydigan xatolar
- 8. Mashqlar
- 1-mashq (oson): to'ldiring
- 2-mashq (o'rta): hot path'ni toping
- 3-mashq (qiyin): for await mi, 'line' hodisasimi?
- 4-mashq: CLI qadami
- 9. Real ishda
- Xulosa
- Manbalar
Node.js CPU profiling: --cpu-prof, flamegraph va hot path'ni topish
Qisqacha: Sekin kodni taxmin bilan emas, o'lchov bilan topasiz.
node --cpu-prof app.jsdastur tugaganda.cpuprofilefaylini yozadi: har ~1 ms da "hozir qaysi funksiya ishlayapti" namunasi. Undan ikki raqam olinadi: self (funksiyaning o'zida o'tgan vaqt) va total (u chaqirganlar bilan). Flamegraph — shu ma'lumotning rasmi: kenglik — vaqt, balandlik — chaqiruvlar chuqurligi. Kanondavalyuta tahlil(1 mln qator) profili vaqtning 22 % irunMicrotasksga —for awaitning har qatordagi Promise'iga ketishini ko'rsatdi. Biz'line'hodisasi bilan o'lchadik: 645 → 567 ms.
Bu darsda
--cpu-profbilan profil yig'ib,.cpuprofileichini o'zingiz tahlil qilasiz.- Self va total vaqt farqini, "hot path" (issiq yo'l) nimaligini tushuntira olasiz.
- Flamegraph va flame chart'ni o'qiysiz.
- Inlining profilni qanday "aldashini" va qator darajasidagi ma'lumot bilan uni qanday ochishni bilasiz.
--prof/--prof-processva 0x ni qachon ishlatishni bilasiz.
Oldin bilishingiz kerak: Event loop'ni bloklash, Performansni o'lchash va benchmarking, DevTools: Performance paneli, Node'ni debug qilish.
1. Nega bu kerak?
valyuta tahlil katta.csv 1 million qatorni 0.8 soniyada qayta ishlaydi. Tezroq bo'lishi mumkinmi? Qayerni tuzatish kerak? Ko'pchilik "aniq CSV ajratish sekin" deb taxmin qiladi va o'sha joyni qayta yozadi. Keyin o'lchaydi — farq yo'q.
Event loop'ni bloklash darsida qancha vaqt ketishini o'lchadingiz. Profil esa qayerga ketishini ko'rsatadi. Brauzerda DevTools Performance paneli shuni qiladi. Node'da xuddi shu V8 profiler bor.
O'xshatish: oylik xarajat. "Pul qayerga ketyapti?" degan savolga xotiradan javob bersangiz — "ovqatga". Bank ko'chirmasini ochsangiz — taksi, obunalar, mayda xaridlar. Profil — kodingizning bank ko'chirmasi.
2. --cpu-prof: profil yig'ish
2.1 Tajriba dasturi
Kichik hisobot dasturi: 300 000 qator yasaydi, har valyuta o'rtachasini va nechta turli kurs uchraganini hisoblaydi (sekin.mjs, qisqartirilgan):
function parseRow(line) {
const [date, code, rate] = line.split(",");
return { date, code, rate: Number(rate) };
}
function contains(list, value) {
for (const x of list) if (x === value) return true;
return false;
}
function summarize(rows) {
const sums = {};
const seen = []; // turli kurslar
for (const line of rows) {
const r = parseRow(line);
sums[r.code] ??= { n: 0, total: 0 };
sums[r.code].n++;
sums[r.code].total += r.rate;
if (!contains(seen, r.rate)) seen.push(r.rate);
}
// … o'rtachalar va natija satri
}Faylda bu funksiyalar 12–34-qatorlarda (contains ning sikli — 18-qator). Natija:
USD 11497.85 | EUR 11497.85 | RUB 11497.86 | IDR 11497.86 | turli kurs: 9972.2 Profil
node --cpu-prof --cpu-prof-dir=prof sekin.mjsDastur odatdagidek ishlaydi, tugaganda prof/ papkasida fayl paydo bo'ladi:
CPU.20261023.221159.12880.0.001.cpuprofileNom: sana, vaqt, PID va tartib raqami (hujjat bo'yicha CPU.${yyyymmdd}.${hhmmss}.${pid}.${tid}.${seq}.cpuprofile). Bayroqlar:
| Bayroq | Nima |
|---|---|
--cpu-prof |
Profilni yoqish, chiqishda yozish |
--cpu-prof-dir=prof |
Qaysi papkaga |
--cpu-prof-name=… |
Fayl nomi (${pid} o'rinbosari bilan) |
--cpu-prof-interval=100 |
Namuna oralig'i mikrosekundda (sukut 1000) |
Maslahat: Profil yig'ilgan dastur biroz sekinroq ishlaydi va yozish uchun vaqt oladi. Profil ichidagi vaqtlarni oddiy ishga tushirish vaqti bilan aralashtirmang.
2.3 .cpuprofile ichida nima bor
Bu oddiy JSON, uch asosiy maydon bilan:
nodes— chaqiruvlar daraxti: har tugun bitta funksiya chaqiruv yo'lida (callFrame: nomi, fayl, qator),children— u chaqirganlar.samples— har ~1 ms da yozilgan tugun ID'lari: "shu lahzada qaysi tugun ishlayotgan edi".timeDeltas— namunalar orasidagi vaqt (mikrosekund).
Self vaqtni o'zingiz hisoblay olasiz. Quyidagi blok — 4 tugunli qo'lda yozilgan mini-profil (toza JS, saytda ham ishlaydi):
const fn = (functionName) => ({ functionName });
const profile = {
nodes: [
{ id: 1, callFrame: fn("(root)"), children: [2] },
{ id: 2, callFrame: fn("summarize"), children: [3, 4] },
{ id: 3, callFrame: fn("parseRow"), children: [] },
{ id: 4, callFrame: fn("contains"), children: [] },
],
samples: [2, 3, 3, 4, 4, 4, 2, 3, 4, 4],
timeDeltas: new Array(10).fill(1000), // mikrosekund
};
const self = new Map();
profile.samples.forEach((id, i) => {
self.set(id, (self.get(id) ?? 0) + profile.timeDeltas[i] / 1000);
});
const byId = new Map(profile.nodes.map((n) => [n.id, n]));
const total = (id) =>
(self.get(id) ?? 0) +
byId.get(id).children.reduce((sum, c) => sum + total(c), 0);
for (const n of profile.nodes.slice(1)) {
const name = n.callFrame.functionName;
const own = self.get(n.id) ?? 0;
console.log(`${name}: self ${own} ms, total ${total(n.id)} ms`);
}Konsolda:
summarize: self 2 ms, total 10 ms
parseRow: self 3 ms, total 3 ms
contains: self 5 ms, total 5 ms- Self — namuna aynan shu tugunda bo'lgan vaqt.
contains— 5 ms: eng ko'p. - Total — o'zi + bolalarining total'i.
summarizening o'zi atigi 2 ms, lekin total 10 ms — butun ish uning ostida. - Hot path (issiq yo'l) — total eng katta bo'lgan zanjir:
summarize → contains. Optimallashtirishni shu yerdan boshlaysiz.
3. Haqiqiy profil va inlining tuzog'i
3.1 Funksiyalar bo'yicha
Xuddi shu hisobni haqiqiy .cpuprofile uchun yozdik (tahlil-prof.mjs — yuqoridagi blokning to'liq versiyasi, callFrame.url va lineNumber bilan). sekin.mjs profili — contains qatoriga va self/total ustunlariga qarang:
profil: 15 KB, 74 tugun, 252 namuna
jami 416 ms
self % self ms total ms funksiya
37.7 % 157 302 summarize sekin.mjs:22
31.8 % 132 132 parseRow sekin.mjs:12
10.0 % 42 42 (garbage collector) :0
9.5 % 40 40 makeRows sekin.mjs:2
3.1 % 13 13 (program) :0
3.1 % 13 13 contains sekin.mjs:17
2.0 % 8 351 (anonim) sekin.mjs:1Kutilmagan: contains — atigi 3.1 %. Demak muammo unda emasmi? (garbage collector) — xotira tozalash (GC darsi), (program) — Node'ning o'zi, (anonim) sekin.mjs:1 — modulning yuqori darajasi.
3.2 Qatorlar bo'yicha
.cpuprofile da har tugunning positionTicks maydoni bor — qaysi qatorda nechta namuna tushgani. Shu bo'yicha saraladik:
75 namuna (29.8 %) sekin.mjs:18 (summarize)
66 namuna (26.2 %) sekin.mjs:13 (parseRow)
21 namuna (8.3 %) sekin.mjs:6 (makeRows)
15 namuna (6.0 %) sekin.mjs:14 (parseRow)
14 namuna (5.6 %) sekin.mjs:27 (summarize)Birinchi qatorga qarang: 18-qator — bu contains ning sikli (for (const x of list)). Lekin u summarize nomi bilan yozilgan! Sabab — inlining: V8 ning optimallashtiruvchi kompilyatori (TurboFan) kichik va tez-tez chaqiriladigan contains ni summarize ning ichiga "qo'yib yubordi". Mashina kodida endi alohida contains chaqiruvi yo'q — vaqt summarize ga yoziladi, qator raqami esa haqiqatni aytadi.
Diqqat: Funksiyalar ro'yxatida kichik funksiya "arzon" ko'rinsa, unga ishonmang — qatorlar bo'yicha ham qarang. DevTools va VS Code ham
.cpuprofileni ochganda qator darajasidagi vaqtni manba kod yonida ko'rsatadi (hujjat bo'yicha; biz sinamadik).
Yana bir kuzatuv: dastlabki variantda contains o'rniga seen.includes(…) bor edi. O'shanda vaqt umuman sekin.mjs:31 — console.log(summarize(makeRows(…))) qatoriga yozildi. O'rnatilgan metodlar ham chaqiruvchiga "singib" ketishi mumkin — shuning uchun tajriba uchun alohida contains funksiyasini yozdik.
3.3 Tuzatish va qayta o'lchash
contains har qatorda 997 tagacha elementli massivni ko'rib chiqadi — O(n) (Big-O). Set da tekshirish — O(1):
- const seen = []; // turli kurslar
+ const seen = new Set(); // turli kurslar
…
- if (!contains(seen, r.rate)) seen.push(r.rate);
+ seen.add(r.rate);
…
- return `… | turli kurs: ${seen.length}`;
+ return `… | turli kurs: ${seen.size}`;Natija o'zgarmadi (turli kurs: 997). Profil (tez.mjs):
jami 313 ms
self % self ms total ms funksiya
47.4 % 148 148 parseRow tez.mjs:12
14.2 % 44 193 summarize tez.mjs:22
13.8 % 43 43 (garbage collector) :0
13.0 % 41 41 makeRows tez.mjs:218-qator ro'yxatdan yo'qoldi, endi eng issiq joy — parseRow (split va obyekt yaratish). Oddiy ishga tushirish vaqti (7 marta, mediana, ikki seans):
- sekin (massiv + contains), 1-seans471 ms
- tez (Set), 1-seans386 ms
- sekin, 2-seans494 ms
- tez, 2-seans334 ms
Manba: O'lchandi: Node 24.21.0, Windows 11, i5-12500H, 2026-10-23 (mashina parallel ishlar bilan band edi)
Ikki seans orasida ham raqamlar tebrandi — mashina boshqa ishlar bilan band edi. Shuning uchun har doim oldin va keyin bitta seansda o'lchang. Farq barqaror: ~85–160 ms.
Keyingi qadam — parseRow. Lekin to'xtang: dastur 0.4 soniyada tugaydi va kuniga bir marta ishlaydi. Optimallashtirish — vaqt sarfi. Profil "qayerda" ni aytadi, "arziydimi" ni siz hal qilasiz.
Tekshirib ko'ring: Profilda
formatSanafunksiyasining self vaqti 2 %, total vaqti 60 %. Uni qayta yozish dasturni tezlashtiradimi?
Javob
Uning o'zini qayta yozish deyarli foyda bermaydi — self atigi 2 %. 60 % uning chaqirgan funksiyalarida (total). formatSana ostidagi daraxtga qarang: qaysi bola katta self vaqtga ega? Ehtimol Intl.DateTimeFormat har chaqiruvda qayta yaratilyapti — uni bir marta yaratib, qayta ishlatish kerak. Yoki inlining bo'lgan — qatorlar ro'yxatiga qarang.
4. Flamegraph va flame chart
.cpuprofile — raqamlar. Ko'z uchun uni rasmga aylantiramiz.
Flamegraph (alanga grafigi) — har to'rtburchak — funksiya, kengligi — total vaqti, ustidagilar — u chaqirgan funksiyalar. Vaqt tartibi yo'q: bir xil yo'llar birlashtiriladi. Keng va "yassi" tepalik — hot path.
Flame chart — gorizontal o'q vaqt: chap — dastur boshi, o'ng — oxiri. DevTools Performance panelida ko'rgansiz. Qachon nima bo'lganini ko'rsatadi (masalan, boshida makeRows, keyin summarize).
Bizning sekin.mjs profilini flamegraph sxemasida chizsak:
flowchart TB
R["(anonim) sekin.mjs — total 351 ms"]
R --> S["summarize — total 302 ms<br/>self 157 (18-qator: contains)"]
R --> M["makeRows — 40 ms"]
S --> P["parseRow — 132 ms"]
S --> C["contains — 13 ms<br/>(qolgani inlining bilan summarize'da)"]Bu diagramma — flamegraph emas, uning daraxt ko'rinishi (raqamlar — yuqoridagi haqiqiy profildan). Haqiqiy flamegraph'da summarize to'rtburchagi butun kenglikning ~85 % ini egallaydi, makeRows esa yonida tor ustun.
Qayerda ko'rish mumkin (hujjat bo'yicha; agent muhitida brauzer va VS Code ochilmagan — sinalmagan):
- Chrome DevTools → Performance paneli → "Load profile" →
.cpuprofile. - VS Code —
.cpuprofilefaylini ochish: o'rnatilgan ko'ruvchi jadval va flame ko'rinishini beradi. chrome://inspectorqali jonli jarayon → Profiler/Performance (debug darsi).- speedscope.app kabi veb ko'ruvchilar
.cpuprofileni qabul qiladi (fayl brauzerda ochiladi; maxfiy kod bo'lsa — lokal versiyasini ishlating).
5. Boshqa vositalar
5.1 --prof va --prof-process
Eski, lekin hali ishlaydigan yo'l: V8 "tick" jurnali. Biz sinadik:
node --prof sekin.mjs
node --prof-process isolate-0000017E7F384000-3352-v8.logChiqishdan (qisqartirilgan):
Statistical profiling result from isolate-…-v8.log, (40 ticks, 1 unaccounted, 0 excluded).
[JavaScript]:
ticks total nonlib name
12 30.0% 70.6% JS: *summarize file:///C:/Users/…/sekin.mjs:22:19
2 5.0% 11.8% Builtin: StringAdd_CheckNone
[Summary]:
ticks total nonlib name
16 40.0% 94.1% JavaScript
3 7.5% 17.6% GC
23 57.5% Shared libraries- Nom oldidagi belgi — kod qaysi bosqichda ishlagan:
*— TurboFan optimallashtirgan,+— Maglev,^— Sparkplug,~— interpretator (Ignition).*summarize— eng tez rejimda. - Halol eslatma: 0.5 soniyalik dasturda atigi 40 tick chiqdi —
--cpu-profesa 252 namuna berdi. Bizning Windows mashinamizda--profjuda siyrak yozdi; Linux'da farq qilishi mumkin (sinalmagan). Qisqa dasturlar uchun--cpu-profishonchliroq. --profning afzalligi: C++ va tizim kutubxonalaridagi vaqtni ham ajratadi (Shared libraries).
5.2 0x va boshqalar
- 0x — bitta buyruq bilan flamegraph HTML yasaydi (
npx 0x app.js). npm'da 6.0.0 (2026-10-23 holatiga, oxirgi o'zgarish 2025-07). Biz o'rnatmadik. node:inspectormoduli — profilni dastur ichidan yoqish (Profiler.start/stop), masalan faqat sekin so'rov paytida.- APM xizmatlari (Datadog, New Relic) — production profiling; kursning keyingi qismlarida. Eski maqolalarda Clinic.js ni ko'rasiz — uning README'si 2026-10 holatiga loyiha faol qo'llab-quvvatlanmasligini va natijalari Node'ning yangi versiyalarida noaniq bo'lishi mumkinligini aytadi. Yangi loyihada
--cpu-profdan boshlang.
6. CLI qadami: valyuta tahlil profili
Yangi holat yo'q — kanon profil yig'di, lekin kodni o'zgartirmadi. Kanon tajribasi (t47): node --cpu-prof dist/bin.js tahlil katta.csv (1 mln qator) → .cpuprofile 50 KB, 257 tugun, 601 namuna:
55.3 % 544 ms tahlilQil tahlil.js:35
22.2 % 218 ms runMicrotasks :0
3.7 % 37 ms (anonim) interface:621
3.4 % 34 ms (garbage collector) :0
1.9 % 19 ms (program) :0
1.4 % 14 ms csvniAjrat tahlil.js:7tahlilQil— 55 %: asosiy sikl (min, max, o'rtacha).runMicrotasks— 22 %:for await (const qator of rl)har qator uchun Promise yaratadi va microtask navbatidan o'tkazadi (microtask darsi).csvniAjrat— 1.4 %. "CSV ajratish sekin" degan taxmin noto'g'ri edi.
Kanon bu yerda to'xtadi: readline'ning 'line' hodisasi tezroq bo'lishi mumkin — o'lchanmagan. Biz uni alohida o'lchadik (44 MB, 1 000 001 qatorli CSV, har qatordan kursni yig'ish, 7 marta mediana):
rl-await.mjs mediana 645 ms (min 603 max 765, n=7)
rl-event.mjs mediana 567 ms (min 536 max 611, n=7)'line' hodisasi bilan ~12 % tez. Lekin valyuta da bu o'zgarish kiritilmadi: for await kodi qisqaroq, xatolar try/catch bilan tabiiy ushlanadi, va bu farq 1 mln qatorda 80 ms. Kundalik CBU tarixi bir necha yuz qator — farq sezilmaydi. Bu — 3-mashq.
7. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
| Taxmin bilan optimallashtirildi, farq yo'q | Hot path boshqa joyda | Avval profil |
| Kichik funksiya profilda "arzon" | Inlining — vaqt chaqiruvchida | positionTicks / qator ko'rinishi |
.cpuprofile yozilmadi |
Dastur process.exit() yoki signal bilan uzildi |
Normal tugashini ta'minlang |
| Self kichik, total katta funksiyani qayta yozish | Vaqt bolalarida | Daraxtda pastga tushing |
| Ikki o'lchov solishtirilmaydi | Har xil seans, mashina yuki | Bitta seansda, bir necha marta, mediana |
--prof juda kam tick |
Siyrak namuna (bizda Windows) | --cpu-prof |
| Profil ostida dastur sekin | Profiler narxi | Absolyut vaqtni profilsiz o'lchang |
8. Mashqlar
Yechimlar kurs/mashqlar/24/47-cpu-profil/ da.
1-mashq (oson): to'ldiring
- Funksiyaning faqat o'zida o'tgan vaqt —
- Funksiya va u chaqirganlar bilan birga —
- Profilni yozadigan Node bayrog'i —
-- - Flamegraph'da to'rtburchak kengligi nimani bildiradi?
- Kichik funksiya vaqtining chaqiruvchiga yozilishiga sabab —
Yechim
- self — namuna aynan shu funksiyada.
- total — self + bolalarining total'i.
- cpu-prof —
.cpuprofileJSON yozadi. - vaqt — total vaqt (tartib emas — u flame chart'da).
- inlining — TurboFan kichik funksiyani chaqiruvchi ichiga qo'yadi.
2-mashq (o'rta): hot path'ni toping
Mini-profil uchun hotPath(profile) funksiyasini yozing: (root) dan boshlab har qadamda total'i eng katta bolaga tushadi va funksiya nomlari zanjirini qaytaradi ("a → b → c"). Darsdagi total hisobini qayta ishlating. Toza JS — saytda ham sinang.
Yechim
function hotPath(profile) {
const self = new Map();
profile.samples.forEach((id, i) => {
self.set(id, (self.get(id) ?? 0) + profile.timeDeltas[i]);
});
const byId = new Map(profile.nodes.map((n) => [n.id, n]));
const total = (id) =>
(self.get(id) ?? 0) +
byId.get(id).children.reduce((sum, c) => sum + total(c), 0);
const path = [];
let node = profile.nodes[0];
while (node.children.length > 0) {
const next = node.children
.map((id) => byId.get(id))
.reduce((a, b) => (total(b.id) > total(a.id) ? b : a));
path.push(next.callFrame.functionName);
node = next;
}
return path.join(" → ");
}
const fn = (functionName) => ({ functionName });
const profile = {
nodes: [
{ id: 1, callFrame: fn("(root)"), children: [2, 5] },
{ id: 2, callFrame: fn("summarize"), children: [3, 4] },
{ id: 3, callFrame: fn("parseRow"), children: [] },
{ id: 4, callFrame: fn("contains"), children: [] },
{ id: 5, callFrame: fn("makeRows"), children: [] },
],
samples: [2, 3, 3, 4, 4, 4, 5, 5, 3, 4],
timeDeltas: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
};
console.log(hotPath(profile));Konsolda:
summarize → containssummarize total 8 (makeRows 2), uning ichida contains 4 > parseRow 3. Haqiqiy vositalar (DevTools'ning "Heavy (Bottom Up)" va "Tree" ko'rinishlari) shu ikki yo'nalishda — yuqoridan va pastdan — ko'rsatadi.
3-mashq (qiyin): for await mi, 'line' hodisasimi?
Kanon savoli: readline ni for await o'rniga 'line' hodisasi bilan o'qish tezroqmi? Ikkita fayl yozing — har biri katta.csv dagi qatorlarni sanaydi va 5-ustun (kurs) yig'indisini chiqaradi. CSV yasovchi skript ham yozing (1 mln qator). Har birini 7 marta alohida jarayonda ishga tushirib, medianani solishtiring. Blok Node uchun; o'lchov vaqtga bog'liq — natijangiz boshqacha bo'ladi.
Yechim
'line' hodisasi bilan o'qish (rl-event.mjs):
import { createReadStream } from "node:fs";
import { createInterface } from "node:readline";
import { once } from "node:events";
let n = 0;
let sum = 0;
const rl = createInterface({
input: createReadStream("katta.csv"),
crlfDelay: Infinity,
});
rl.on("line", (line) => {
n++;
sum += Number(line.split(",")[4]) || 0;
});
await once(rl, "close");
console.log(n, sum.toFixed(0));rl-await.mjs — xuddi shu, faqat for await (const line of rl) { … }. Ikkalasi bir xil natija berdi: 1000001 11497995554 (sarlavha qatori ham sanaladi, uning kursi NaN → || 0). Bizning o'lchov (Node 24.21.0, Windows 11): for await 645 ms, 'line' 567 ms — ~12 % tez.
Nega? for await har qator uchun async iterator'ning next() Promise'ini yaratadi va hal qiladi — kanon profilidagi runMicrotasks 22 % aynan shu. Hodisa esa oddiy sinxron callback. Narxi: hodisa ichidagi xato for await dagidek try/catch ga tushmaydi, oqimni to'xtatish (break) ham qiyinroq. valyuta uchun 80 ms/1 mln qator — qulaylik ustun. Yechim fayllari: rl-await.mjs, rl-event.mjs, csv.mjs, vaqt.mjs.
4-mashq: CLI qadami
valyuta uchun profil yig'ing. Qadamlar. (1) 1 mln qatorli CSV yasang (sarlavha: sana,kod,nomi,nominal,kurs,farq). (2) npm run build, keyin node --cpu-prof --cpu-prof-dir=prof dist/bin.js tahlil katta.csv; (3) darsdagi tahlil skripti bilan top-5 ni chiqaring; (4) agar imkoningiz bo'lsa — .cpuprofile ni DevTools yoki VS Code'da oching va flamegraph'da runMicrotasks ni toping. Kodni o'zgartirmang, commit kerak emas.
Yechim
Kanon natijasi «CLI qadami» bo'limida: tahlilQil ~55 %, runMicrotasks ~22 %. Sizda foizlar yaqin, millisekundlar boshqa bo'ladi. Agar top'da csvniAjrat katta chiqsa — CSV'ingizda qo'shtirnoqli maydonlar ko'p ("…"), ajratish murakkablashgan. prof/ ni .gitignore ga qo'shing — profil fayllari repozitoriyga kerak emas.
9. Real ishda
- Serverlarda sekin endpoint —
--cpu-profbilan lokal yuk ostida (autocannon kabi vosita bilan) yoki production'da APM xizmati orqali. - "Avval o'lcha" — eng muhim odat: profil ko'rsatmagan joyni optimallashtirmang.
- Event loop bloklash (oldingi dars) va CPU profil birga: kechikish bor → profil qaysi funksiya bloklayotganini ko'rsatadi.
- Intervyu savollari: "Node ilovasi sekin — qayerdan boshlaysiz?", "Self va total time farqi?", "Flamegraph qanday o'qiladi?".
Xulosa
node --cpu-prof→.cpuprofile(JSON:nodes,samples,timeDeltas,positionTicks).- Self — funksiyaning o'zi, total — bolalari bilan; hot path — total bo'yicha eng og'ir zanjir.
- Inlining kichik funksiya vaqtini chaqiruvchiga yozadi — qator darajasida tekshiring (biz ko'rdik:
contains3 %, uning qatori 30 %). - Flamegraph — kenglik = vaqt, flame chart — o'q = vaqt tartibi; DevTools/VS Code'da ko'rish — sinalmagan.
- Kanon:
valyuta tahlildarunMicrotasks22 %;'line'hodisasi 645 → 567 ms, lekin kodga kiritilmadi.
Keyingi dars: Memory leak'ni topish: heap snapshot — xotira sekin o'sib borsa, ikki snapshot farqidan aybdorni topish.
Manbalar
- Node.js 24 hujjati — CLI (
--cpu-prof,--cpu-prof-dir,--cpu-prof-name,--cpu-prof-interval,--prof): https://nodejs.org/docs/latest-v24.x/api/cli.html - Clinic.js README ("not being actively maintained" eslatmasi), 2026-10-23: https://github.com/clinicjs/node-clinic
- Node.js — Profiling Node.js applications (
--prof,--prof-process): https://nodejs.org/learn/getting-started/profiling - Chrome DevTools Protocol — Profiler domain (
.cpuprofiletuzilmasi,positionTicks): https://chromedevtools.github.io/devtools-protocol/tot/Profiler/ - 0x 6.0.0 — npm reestri, 2026-10-23.
- Kanon:
t47-profil(valyuta tahlil, 1 mln qator).sekin.mjs/tez.mjsprofillari, qator tahlili,--prof,for awaitva'line'o'lchovi — biz ishga tushirdik (Node 24.21.0, Windows 11, i5-12500H).
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!