Ders 16 / 17
Başarım Profilleme
Ana iş parçacığı zaman çizelgesinin okunması, uzun görev kavramı, olay döngüsü gecikmesi, örnekleyici profilcinin kaydettikleri ve uzun işi bölerek sıra vermenin gözlenebilir etkisi.
İçindekiler
Bir program bellek sızdırmadan da kötü çalışabilir. Kullanıcının gördüğü şey bellek grafiği değil, tıklamaya geç yanıt veren bir arayüz ya da yanıt süresi dalgalanan bir hizmettir.
Bu dersin ölçütü bellekten farklıdır: iş parçacığının ne kadar süreyle tek bir işe kilitlendiği. Kursun ilk dersindeki engelleme kavramı burada ölçülebilir hale gelir.
Ders boyunca hiçbir süre değeri yazdırılmayacak; süreler makineye ve yüke göre değişir ve yazıldıklarında yanıltıcı olurlar. Ölçülen şey sıradır, gösterilen şey yöntemdir.
Uzun Görev
Olay döngüsü, her turda görev kuyruğundan bir iş alır ve sonuna kadar çalıştırır. Bu iş uzun sürerse, o süre boyunca hiçbir tıklama işlenmez, hiçbir yanıt ayrıştırılmaz, hiçbir çizim yapılmaz.
Belirli bir eşiği aşan görevlere uzun görev (long task) denir. Eşik ortama göre tanımlanır; tarayıcı ölçüm arayüzlerinde elli milisaniye yaygın bir sınırdır. Sayının kendisi değil, ardındaki akıl yürütme önemlidir: kullanıcı etkileşiminin akıcı sayılması için iş parçacığının düzenli aralıklarla serbest kalması gerekir.
Uzun görevin ikinci ölçüsü olay döngüsü gecikmesi (event loop lag) olarak adlandırılır. Yöntemi doğrudandır: bilinen bir gecikmeyle bir zamanlayıcı kurulur ve geri çağrının gerçekte ne kadar geç çalıştığına bakılır. Fark, o anda iş parçacığının ne kadar meşgul olduğunun ölçüsüdür. Sunucu tarafında bu değer, yanıt sürelerinin dalgalanmasını açıklayan ilk göstergedir.
Bölmek ve Sıra Vermek
Uzun bir işi hızlandırmak her zaman mümkün değildir; ama bölmek çoğu zaman mümkündür. Bölünmüş iş, parçalar arasında olay döngüsüne sıra verir ve bekleyen görevler araya girer.
function meshgulBekle(sure) { const bitis = Date.now() + sure; while (Date.now() < bitis) { // İş parçacığını kasten meşgul tutar. } } function siraVer() { return new Promise((karar) => setTimeout(karar, 0)); } async function tekParcaIsle() { setTimeout(() => console.log(" araya giren görev"), 0); meshgulBekle(60); console.log(" işleme bitti"); await siraVer(); } async function parcaliIsle() { setTimeout(() => console.log(" araya giren görev"), 0); for (let i = 1; i <= 3; i += 1) { meshgulBekle(20); console.log(" parça", i, "bitti"); await siraVer(); } } console.log("tek parçalı işleme:"); await tekParcaIsle(); console.log("bölünmüş işleme:"); await parcaliIsle();
tek parçalı işleme: işleme bitti araya giren görev bölünmüş işleme: parça 1 bitti araya giren görev parça 2 bitti parça 3 bitti
Tek parçalı işlemede bekleyen görev en sona kaldı; bölünmüş işlemede birinci parçadan hemen sonra araya girdi. Toplam iş aynıdır — her iki durumda da altmış milisaniyelik meşguliyet vardır. Değişen, bekleyen işin ne kadar beklediğidir.
Sıra vermenin bir mikro görevle yapılamayacağı da burada görülür. Olay döngüsü dersindeki
kural gereği mikro görev kuyruğu tamamen boşaltılır; queueMicrotask ya da beklemede
olmayan bir söz beklemek görev kuyruğuna sıra vermez. Gerçek sıra, görev kuyruğuna
dönmekle verilir.
Bölmenin bedeli de vardır: parça sayısı arttıkça tur başına ek maliyet ödenir ve toplam süre uzar. Doğru parça boyutu, “tepki verilebilir kalmak” ile “verimli çalışmak” arasındaki dengedir. Hesap yükü gerçekten ağırsa doğru yanıt bölmek değil, işi ayrı bir yürütme bağlamına taşımaktır.
Ölçüm İmleri
Nerede zaman harcandığını görmek için önce ölçülecek aralıkların adlandırılması gerekir. Standart ölçüm arayüzü iki kavram sunar: belirli bir anı işaretleyen im (mark) ve iki im arasını adlandıran ölçüm (measure).
import { PerformanceObserver, performance } from "node:perf_hooks"; function meshgulBekle(sure) { const bitis = Date.now() + sure; while (Date.now() < bitis) { // İş parçacığını kasten meşgul tutar. } } const gozlemci = new PerformanceObserver((liste) => { for (const giris of liste.getEntries()) { console.log("kayıt:", giris.entryType, "—", giris.name, "— süre ölçüldü mü:", giris.duration > 0); } }); gozlemci.observe({ entryTypes: ["measure"] }); performance.mark("ayrıştırma-başladı"); meshgulBekle(20); performance.mark("ayrıştırma-bitti"); meshgulBekle(10); performance.mark("yazma-bitti"); performance.measure("ayrıştırma", "ayrıştırma-başladı", "ayrıştırma-bitti"); performance.measure("yazma", "ayrıştırma-bitti", "yazma-bitti"); performance.measure("toplam", "ayrıştırma-başladı", "yazma-bitti"); await new Promise((karar) => setTimeout(karar, 10)); gozlemci.disconnect();
kayıt: measure — ayrıştırma — süre ölçüldü mü: true kayıt: measure — toplam — süre ölçüldü mü: true kayıt: measure — yazma — süre ölçüldü mü: true
Süre değerleri yazdırılmadı; yalnız ölçümün gerçekleştiği doğrulandı. Çıktı sırası da öğreticidir: kayıtlar oluşturulma sırasına göre değil başlangıç anına göre sıralanır. “toplam” ölçümü en son oluşturuldu ama “ayrıştırma” ile aynı imden başladığı için ikinci sırada göründü.
İmlerin değeri, ölçümü koda gömülü ve adlandırılmış hale getirmesidir. Eşzamansız bir akışta bir işlemin başlangıcı ve bitişi farklı turlarda gerçekleşir; im olmadan bu iki an aynı ölçüde bağlanamaz.
Örnekleyici Profil
İm koymak, nereye bakılacağı bilindiğinde işe yarar. Bilinmediğinde profilci kullanılır.
Yaygın yöntem örneklemedir (sampling): profilci düzenli aralıklarla çağrı yığıtının anlık kopyasını alır. Sonuçta hangi işlevin kaç örnekte yığıtın tepesinde olduğu bilinir; bu, işlevlere düşen süre payının istatistiksel tahminini verir.
Yöntemin iki özelliği sonucun okunuşunu belirler. Ölçüm yaklaşıktır — çok kısa süren bir işlev hiçbir örneğe düşmeyebilir. Buna karşılık maliyeti düşüktür ve programın davranışını belirgin biçimde değiştirmez.
Profil, çalışma zamanının hata ayıklama arayüzünden alınır ve düğümleri çağrı çerçevesi bilgisi taşır.
import { Session } from "node:inspector/promises"; function meshgulBekle(sure) { const bitis = Date.now() + sure; while (Date.now() < bitis) { // İş parçacığını kasten meşgul tutar. } } const oturum = new Session(); oturum.connect(); await oturum.post("Profiler.enable"); await oturum.post("Profiler.start"); meshgulBekle(60); const { profile } = await oturum.post("Profiler.stop"); oturum.disconnect(); console.log("profil alanları:", Object.keys(profile).sort().join(", ")); console.log("örnek alındı mı:", profile.samples.length > 0); console.log("düğümlerde kendi işlevimiz var mı:", profile.nodes.some((d) => d.callFrame.functionName === "meshgulBekle"));
profil alanları: endTime, nodes, samples, startTime, timeDeltas örnek alındı mı: true düğümlerde kendi işlevimiz var mı: true
Alan adları profilin yapısını açıklar. nodes, çağrı ağacının düğümleridir; her düğüm bir
işlevi ve onun çağrı çerçevesini temsil eder. samples, alınan her örnekte yığıtın
tepesindeki düğümün kimliğidir. timeDeltas, ardışık örnekler arasındaki süredir. Arayüz
tabanlı araçların çizdiği alev grafiği, bu üç dizinin görselleştirilmesinden başka bir şey
değildir.
Grafiği okumanın kuralı da buradan çıkar: genişlik süredir, yükseklik çağrı derinliğidir. Geniş ve alçak bir blok, tek bir işlevin uzun süre çalıştığını; dar ve derin bir yığın ise çok sayıda kısa çağrıyı gösterir.
Ne Ölçülmemeli
Üç yaygın hata sonuçları kullanılamaz hale getirir.
Tek bir çalıştırmanın süresi ölçüm sayılmaz. İlk çalıştırmada derleme ve önbellek ısınması maliyeti vardır; ölçüm tekrarlanmalı ve dağılıma bakılmalıdır.
Ortalama tek başına yeterli değildir. Kullanıcı deneyimini belirleyen, uç değerlerdir; yavaş yüzdelik dilimler ayrıca izlenmelidir.
Eşzamansız bir akışın “süresi”, işlevlerin toplam çalışma süresi değildir. Beklemede geçen zaman iş parçacığını meşgul etmez; profilcide görünmez ama kullanıcı için gerçektir. Bu nedenle profil ile uçtan uca ölçüm birlikte okunur.
Özet
- Uzun görev, iş parçacığını tek bir işe kilitleyen ve bekleyen bütün işleri geciktiren görevdir; olay döngüsü gecikmesi bunun ölçüsüdür.
- Uzun bir işi bölüp görev kuyruğuna sıra vermek, bekleyen işlerin araya girmesini sağlar; mikro görevle sıra verilemez.
- İm ve ölçüm arayüzü, eşzamansız akışta farklı turlara düşen anları adlandırılmış aralıklara bağlar; kayıtlar başlangıç anına göre sıralanır.
- Örnekleyici profilci, düzenli aralıklarla çağrı yığıtının kopyasını alır; sonucu çağrı ağacı düğümleri, örnekler ve süre farklarından oluşur.
- Tek çalıştırma, yalnız ortalama ve yalnız profil verisi yanıltıcıdır; ölçüm tekrar, dağılım ve uçtan uca süreyle birlikte okunur.
Sonraki Adım
Ölçüm nerede zaman harcandığını söyler, ama neyin yanlış olduğunu söylemez. Kursun son dersi tanı araçlarının ikinci yarısını ele alıyor: programı belirli bir noktada durdurup durumunu incelemek. Kesme noktaları, adımlama, gözlem ifadeleri ve eşzamansız çağrı yığıtlarının okunması — hepsi ölçüm akışının aynı örneği üzerinde gösterilecek.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.