---
title: 'Gecikme ve Verim'
source: 'https://academia.sh/tr/kurslar/sistem-tasarimina-giris/gecikme-ve-verim'
course: 'Sistem Tasarımına Giriş'
language: tr
updated: '2026-08-17T18:10:57+00:00'
license: 'CC BY-SA 4.0'
---

# Gecikme ve Verim

İki ölçütün birbirinden bağımsız iki eksen olduğunun ölçülmesi: eşzamanlılık artarken verimin doyması ve gecikmenin kötüleşmesi, eşzamanlılık ile verim ve gecikme arasındaki bağıntının ölçümle doğrulanması, doyuma yaklaşmanın gecikme maliyetinin bir kuyruk modeliyle gösterilmesi ve her sayının varsayım, hesap ya da ölçüm olarak sınıflandırılması.

Önceki konu bir tasarımın nasıl kurulduğunu ve nasıl anlatıldığını ele aldı: bileşenlerin
ayrılması, gereksinimin işlevsel ve işlevsel olmayan yarılarına bölünmesi, kaynak ihtiyacının
kabaca hesaplanması ve her kararın bir gerekçeyle sunulması. Gerekçenin dayandığı şey ise
adlandırılmadı. "Bu tasarım hızlıdır", "bu tasarım ölçeklenir", "bu tasarım ayakta kalır"
cümlelerinin hiçbiri bir ölçüt içermez; üçü de tartışmayı bitirmek yerine başlatır, çünkü
karşı taraf aynı cümleyi tersine çevirdiğinde elde ölçülecek bir şey kalmaz.

Bu konu o ölçütleri tanımlar. İlk ders en sık birbirine karıştırılan çiftle başlar: bir önceki
konuda eşiklerde geçen "takip yanıtı ortancası" ile "depoya ulaşan istek hızı" iki ayrı ölçütün
adıdır ve ikisi arasında hiçbir zorunlu bağ yoktur. Dersin işi bu bağımsızlığı bir düzenekte
ölçmek, sonra bağımsızlığın nerede bittiğini ve neden bittiğini göstermektir.

## Üç Akış ve Sayının Sınıfı

Kurs boyunca aynı sistem ele alınır: bir **gönderi takip ve ücretlendirme servisi**. Üç akışı
vardır. **Okuma** akışı takip sorgusudur: kullanıcı bir takip numarası verir, gönderinin son
durumunu alır. **Yazma** akışı taşıyıcıdan gelen durum olayıdır: küçük kayıtlar sürekli akar.
**Toplu** akış satıcının gün sonu ücretlendirmesidir: günde bir kez, çok büyük bir iş.

Bu konu yeni varsayım seçmez. Kabaca Büyüklük Hesabı dersinin on iki satırlık varsayım tablosu
ve ondan çıkan hesaplar burada girdi olarak kullanılır. Üç akışın ihtiyaç duyulan sayıları
şunlardır: uçta tepe istek hızı **513,89 istek/s** — 416,67'si okuma, 97,22'si yazma; önbelleğin
arkasında depoya ulaşan tepe hız **138,89 istek/s**; gün sonu işi otuz günü kapsayan **12
milyon kaydı dört saatlik pencerede** tarar, yani **833,33 kayıt/s** ve kayıt başına 1,20 ms.
Hepsi hesap sınıfındadır ve hiçbiri dışarıdan alınmamıştır.

Sistem Tasarımı Nedir dersinde kurulan sınıflandırma bu konunun bütün sayılarında da uygulanır:
bir sayı ya seçilmiş bir **varsayım**dır, ya varsayımlardan çıkan bir **hesap**tır, ya da bir
düzenekten alınmış bir **ölçüm**dür. Bu dersin katkısı üçüncü sınıftadır — yukarıdaki hesaplar
gereken kapasiteyi söylüyor, ama bir sürecin ne taşıdığını söylemiyor. O sayı ölçülür.

## İki Ölçüt İki Ayrı Eksendir

**Gecikme** (latency) bir işin başlangıcından bitişine kadar geçen süredir; birimi zamandır.
Ağ Modelleri ve Protokoller kursunda dört bileşene ayrılmıştı: iletim, yayılım, kuyruk ve
işleme. **Verim** (throughput) birim zamanda tamamlanan iş sayısıdır; birimi iş bölü zamandır.
İki ölçütün birimleri farklıdır, dolayısıyla biri ötekinin yerine kullanılamaz.

Üç akış bu iki ekseni ayrı köşelere yerleştirir. Takip sorgusu düşük gecikme ister; kullanıcı
yanıtı bekler ve tek bir yanıtın süresi doğrudan ona görünür. Gün sonu
ücretlendirmesi yüksek verim ister; 12 milyon kaydın dört saatte taranması gerekir ve tek tek
hiçbir kaydın ne zaman bittiği önemli değildir. Aynı sistemin bir akışında milisaniye,
ötekinde saat ölçek birimidir.

Ayrımın kritik sonucu şudur: bir akışın verimini artırmak gecikmesini kötüleştirebilir. Gün sonu
işi kayıtları gruplayarak verimini katlayabilir, ama gruplanan her kayıt grubun tamamlanmasını
bekler. Tersi de olur: gecikmeyi kısaltmak verimi düşürebilir, çünkü her işi hemen başlatmak
gruplamanın kazancından vazgeçmek demektir.

İki ölçütün bir asimetrisi daha vardır. Verim tek bir sayıdır: birim zamanda tamamlanan iş
sayısı sayılır ve biter. Gecikme tek bir sayı değildir, bir **dağılımdır**; aynı yükte bazı
istekler hızlı, bazıları yavaş yanıtlanır. Bu yüzden gecikme **yüzdeliklerle** bildirilir:
ortanca isteklerin yarısının altında kaldığı süre, p99 yüzde birinin aştığı süredir. Ortalama
gecikme bildirmek en az bilgi taşıyan seçenektir, çünkü tek bir çok yavaş istek ortalamayı
kaydırır ve dağılımın biçimini saklar.

## Eşzamanlılık Arttıkça Ne Oluyor

Aşağıdaki düzenek takip ucunu yerel bir sunucu olarak kurar. Her istek iki şey harcar: kayıt
aramasının yerine geçen bir bekleme ve bir işlemci payı. İkisi de düzeneğin parametresidir,
ölçüm değildir.

```js
// takip/sunucu.mjs — takip sorgusu ucu: her istek bir bekleme ve bir islemci payi harcar
import { createServer } from "node:http";

const BEKLEME = 3;                 // kayit aramasinin yerine gecen bekleme (ms), duzenegin parametresi
const ISLEMCI = 0.20;              // istek basina islemci payi (ms), duzenegin parametresi

function isle(ms) {               // ms kadar islemci mesgul eder
  const bit = performance.now() + ms;
  let t = 0;
  while (performance.now() < bit) t += 1;
  return t;
}

const port = Number(process.argv[2]);
if (Number.isInteger(port) === false) console.log("kullanim: node takip/sunucu.mjs <baglanti-noktasi>");
else createServer(async (istek, yanit) => {
  const no = new URL(istek.url, "http://yerel").searchParams.get("no") ?? "-";
  await new Promise((c) => setTimeout(c, BEKLEME));
  isle(ISLEMCI);
  const govde = JSON.stringify({ no, durum: "aktarma merkezinde", bolge: "35", adim: 4 });
  yanit.writeHead(200, { "content-type": "application/json" });
  yanit.end(govde);
}).listen(port);
```

İstemci yedi **eşzamanlılık** (concurrency) düzeyinde çalışır. Her düzeyde belirtilen sayıda
istek hep havada tutulur; iki saniye boyunca gönderilen istek sayısı verimi, tek tek ölçülen
süreler gecikme yüzdeliklerini verir.

```js
// takip/yukle.mjs — artan escamanlilikla istek gonderir; her duzeyde verim ve gecikme yazar
import { Agent, request } from "node:http";

const port = Number(process.argv[2]);
const DUZEY = [1, 2, 4, 8, 16, 32, 64];
const SURE = 2000;                 // her duzeyin olcum suresi (ms)

const agent = new Agent({ keepAlive: true, maxSockets: 256 });

function birIstek(no) {
  return new Promise((coz, sap) => {
    const bas = performance.now();
    const r = request({ port, path: `/takip?no=${no}`, agent }, (y) => {
      y.resume();
      y.on("end", () => coz(performance.now() - bas));
    });
    r.on("error", sap);
    r.end();
  });
}

function yuzdelik(dizi, p) {
  const s = [...dizi].sort((a, b) => a - b);
  return s[Math.min(s.length - 1, Math.floor((p / 100) * s.length))];
}

async function duzey(n) {
  const gecikme = [];
  const bit = performance.now() + SURE;
  const bas = performance.now();
  await Promise.all(Array.from({ length: n }, async (_, k) => {
    let i = 0;
    while (performance.now() < bit) gecikme.push(await birIstek(`G${k}-${i++}`));
  }));
  const gecen = (performance.now() - bas) / 1000;
  return { n, istek: gecikme.length, verim: gecikme.length / gecen,
    orta: yuzdelik(gecikme, 50), p99: yuzdelik(gecikme, 99) };
}

if (Number.isInteger(port) === false) console.log("kullanim: node takip/yukle.mjs <baglanti-noktasi>");
else {
  await birIstek("isinma");
  console.log("escaman  istek   verim(istek/s)  ortanca(ms)  p99(ms)  verim*ortanca");
  for (const n of DUZEY) {
    const s = await duzey(n);
    const little = (s.verim * s.orta) / 1000;
    console.log(`${String(s.n).padStart(6)}  ${String(s.istek).padStart(6)}  ` +
      `${s.verim.toFixed(0).padStart(13)}  ${s.orta.toFixed(2).padStart(10)}  ` +
      `${s.p99.toFixed(2).padStart(7)}  ${little.toFixed(2).padStart(22)}`);
  }
  agent.destroy();
}
```

Sürücü betik sunucuyu başlatır, ölçümü koşturur ve sunucuyu durdurur. Bağlantı noktası numarası
ortama bağlıdır; makinede kullanımdaysa değiştirilmelidir.

```bash
# olc.sh — sunucu baslatilir, yedi escamanlilik duzeyi olculur, sunucu durdurulur
node takip/sunucu.mjs 8811 & SUNUCU=$!
sleep 1
node takip/yukle.mjs 8811
kill $SUNUCU
```

```
escaman  istek   verim(istek/s)  ortanca(ms)  p99(ms)  verim*ortanca
     1     463            231        4.33     4.78                    1.00
     2     936            468        4.46     5.05                    2.09
     4    1764            880        4.80     5.38                    4.23
     8    3038           1515        5.67     6.14                    8.59
    16    4849           2417        6.65     7.57                   16.06
    32    8089           4031        8.21     9.56                   33.10
    64    8593           4268       15.15    16.46                   64.64
```

Bu sayılar ölçümdür ve bu makinede alınmıştır. Mutlak değerleri başka bir makinede
tekrarlanmaz; tekrarlanan şey tablonun **biçimidir**.

## İki Bölge

Tablo iki ayrı bölgeye ayrılır ve dersin savı bu ayrımdadır.

Birinci bölgede, eşzamanlılık 1'den 4'e çıkarken verim 231'den 880'e, yani 3,81 katına çıktı;
ortanca gecikme 4,33 ms'den 4,80 ms'ye, yani 1,11 katına çıktı. Verim neredeyse eşzamanlılıkla
birlikte büyüdü, gecikme yerinde saydı. **Bu bölgede iki ölçüt bağımsızdır:** verim artıyor,
gecikme hakkında hiçbir şey söylemiyor.

İkinci bölgede tablo tersine döner. Eşzamanlılık 32'den 64'e çıkarken verim 4031'den 4268'e,
yani yalnızca 1,06 katına çıktı; ortanca gecikme 8,21 ms'den 15,15 ms'ye, yani 1,85 katına
çıktı. Eşzamanlılığı iki katına çıkarmanın karşılığı %6 verim ve iki kat gecikmedir. **Bu
bölgede bağımsızlık biter:** verim bir üst sınıra dayanmıştır ve eklenen her istek yalnızca
beklemeye eklenir.

Üst sınırın nereden geldiği düzenekte yazılıdır. Her istek 0,20 ms işlemci payı harcıyor ve
sunucu tek bir iş parçacığında çalışıyor; işlemci payı bölünemeyen kaynaktır. Beklemeler
üst üste binebilir, işlemci payı binemez. Sunucu Tarafı Temelleri kursunda kurulan ayrım
budur: bekleyen girdi-çıktı ucuzdur, işlemciyi meşgul eden hesap sırayı kilitler.

## Bağıntı

Son sütun iki ölçütü birbirine bağlar. Her satırda verim ile ortanca gecikmenin çarpımı,
eşzamanlılık düzeyine eşit çıkıyor: 1,00, 2,09, 4,23, 8,59, 16,06, 33,10, 64,64. Bu bir kaza
değil, kuyruk kuramının temel bağıntısıdır. Önbellekleme, Kuyruklar ve Eşzamansız İşleme
kursunda $L = \lambda W$ biçiminde kurulmuştu; buradaki karşılığı şudur:

$$
N = X \times R
$$

$N$ havadaki iş sayısı, $X$ verim, $R$ gecikmedir. Bağıntının tasarım sonucu doğrudandır:
**üç büyüklükten ikisi seçilirse üçüncüsü seçilemez.** Havadaki iş sayısı sabit tutulup verim
artırılamıyorsa, gecikme büyümek zorundadır — başka çıkışı yoktur. İkinci bölgedeki davranış
bu zorunluluğun görünür hâlidir.

Aynı bağıntı ölçüm okumanın kuralını da verir. Yalnız verimi bildiren bir rapor, hangi
eşzamanlılıkta alındığını söylemedikçe gecikme hakkında hiçbir şey söylemez; yalnız gecikmeyi
bildiren bir rapor da yükü söylemedikçe okunamaz. Bir ölçütün tek başına bildirilmesi eksik
bildirimdir.

## Doyuma Yaklaşmanın Bedeli

İkinci bölgenin girişinde ne olduğunu bir model gösterir. Tek sunuculu bir kuyrukta, servis
hızı $\mu$ ve varış hızı $\lambda$ iken **doluluk** (utilization) $\rho = \lambda / \mu$
olarak tanımlanır ve sistemde geçirilen ortalama süre $1 / (\mu - \lambda)$ olur. Aşağıdaki
hesap bu modeli ölçülen üst sınırla besler. **Bu bir modeldir, ölçüm değildir**; varışların
ve servis sürelerinin dağılımı hakkında varsayım içerir ve gerçek bir sunucunun gecikmesini
öngörmez. Gösterdiği şey oranların yönüdür.

```js
// hesap/kuyruk.mjs — tek sunuculu kuyruk MODELI: doyuma yaklasan verimin gecikmeye maliyeti
const MU = 4268;                   // olculen ust sinir: bu duzenekte bir surecin doyum verimi (istek/s)

console.log(`servis hizi mu = ${MU} istek/s (olculen ust sinir)`);
console.log("doluluk   varis hizi(istek/s)   modeldeki ortalama sure(ms)   %30 duruma gore kat");
const taban = 1000 / (MU - 0.30 * MU);
for (const rho of [0.30, 0.50, 0.70, 0.80, 0.90, 0.95, 0.99]) {
  const T = 1000 / (MU - rho * MU);
  console.log(`${(rho * 100).toFixed(0).padStart(6)}%  ${(rho * MU).toFixed(0).padStart(19)}  ` +
    `${T.toFixed(2).padStart(27)}  ${(T / taban).toFixed(1).padStart(18)}`);
}

const tepe = [416.67, 833.33];   // Kabaca Buyukluk Hesabi: tepe okuma hizi ve sorgu varsayimi ikiye katlanirsa
for (const t of tepe) {
  console.log(`tepe ${t} istek/s -> doluluk ${((t / MU) * 100).toFixed(1)}%, ` +
    `ust sinir tepenin ${(MU / t).toFixed(1)} kati, ` +
    `modeldeki ortalama sure ${(1000 / (MU - t)).toFixed(2)} ms`);
}
```

```
servis hizi mu = 4268 istek/s (olculen ust sinir)
doluluk   varis hizi(istek/s)   modeldeki ortalama sure(ms)   %30 duruma gore kat
    30%                 1280                         0.33                 1.0
    50%                 2134                         0.47                 1.4
    70%                 2988                         0.78                 2.3
    80%                 3414                         1.17                 3.5
    90%                 3841                         2.34                 7.0
    95%                 4055                         4.69                14.0
    99%                 4225                        23.43                70.0
tepe 416.67 istek/s -> doluluk 9.8%, ust sinir tepenin 10.2 kati, modeldeki ortalama sure 0.26 ms
tepe 833.33 istek/s -> doluluk 19.5%, ust sinir tepenin 5.1 kati, modeldeki ortalama sure 0.29 ms
```

Model tek bir şeyi söylüyor: dolulukla birlikte verim doğrusal büyürken süre doğrusal
büyümüyor. %30'dan %99'a çıkmak varış hızını 3,3 katına, süreyi 70 katına çıkarıyor. Verimin
son parçası, gecikmenin sınırsız büyümesiyle satın alınır. Doluluğun yüksek tutulması bir
verimlilik başarısı gibi görünür ve bir gecikme kararıdır.

Son iki satır hesabı ölçümle birleştirir. Tepe okuma hızı 416,67 istek/s, düzenekte ölçülen
üst sınır 4268 istek/s; oran 10,2'dir ve doluluk %9,8'de kalır. Kullanıcı başına sorgu iki
katına çıktığında oran 5,1 olur. Buradan çıkan sonuç ölçünün kendisi değil, **yöntemdir**:
tepe hız varsayımlardan hesaplanır, üst sınır düzenekten ölçülür, ikisinin oranı payı verir.
Gerçek takip ucu bu düzenekten fazlasını yapacağı için üst sınırı daha düşük olur; oran ise
aynı biçimde okunur. Oran 1'in altına düştüğünde tasarım artık çalışmıyordur; 2 ile 3
arasındayken tek bir arıza bütün payı silecek kadar dar demektir.

## Özet

- Gecikme bir işin süresi, verim birim zamanda tamamlanan iş sayısıdır; birimleri farklıdır
  ve biri ötekinin yerine kullanılamaz.
- Ölçümde eşzamanlılık 1'den 4'e çıkarken verim 3,81 katına çıktı, ortanca gecikme 1,11
  katında kaldı: bu bölgede iki ölçüt bağımsızdır.
- Eşzamanlılık 32'den 64'e çıkarken verim 1,06 katına çıktı, gecikme 1,85 katına çıktı: verim
  üst sınıra dayandığında eklenen her istek yalnızca beklemeye eklenir.
- Ölçülen her satırda $N = X \times R$ tuttu; üç büyüklükten ikisi seçilirse üçüncüsü seçilemez,
  bu yüzden tek başına bildirilen verim ya da gecikme okunamaz.
- Kuyruk modeli dolulukla sürenin doğrusal büyümediğini gösterdi: %30'dan %99'a varış hızı
  3,3 katına, süre 70 katına çıkıyor; doluluğu yüksek tutmak bir gecikme kararıdır.
- Hesaplanan tepe okuma hızı 416,67 istek/s, ölçülen üst sınır 4268 istek/s; oran 10,2'dir ve
  kullanıcı başına sorgu iki katına çıktığında 5,1'e iner.

## Sonraki Adım

Bu ders tek bir süreci sabit tuttu ve yükü değiştirdi. Ortaya çıkan iki bölge, "bu sistem
hızlıdır" cümlesinin neden yetersiz olduğunu gösterdi: sistemin hızı ölçüldüğü yüke bağlıdır
ve düşük yükte alınmış bir sayı yüksek yükteki davranış hakkında hiçbir şey söylemez. Buradan
iki ayrı soru çıkar. Birincisi, belirli bir yükte sistem ne kadar iyidir. İkincisi, yük
büyüdüğünde bu iyilik ne kadar dayanır. İki soru sık sık tek bir sözcükle karşılanır ve
karşılanmamalıdır: birinin adı başarım, ötekinin adı ölçeklenebilirliktir. Sonraki ders iki
kavramı ayırır: gün sonu işinin iki gerçekleştirimini dört ayrı yükte ölçer, ikisinin de
bugünün eşiğini karşıladığını gösterir ve aradaki farkın ancak yük büyütüldüğünde
sayılabildiğini ortaya koyar.
