---
title: 'Karşılaştırmalı Ölçüm'
source: 'https://academia.sh/tr/kurslar/android-uretim/karsilastirmali-olcum'
course: 'Test, Başarım ve Dağıtım'
language: tr
updated: '2026-10-21T05:02:43+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Karşılaştırmalı ölçümün tek bir sayı yerine tekrarlanan yinelemelerden oluştuğunu açıklar'
    - 'Isınma yinelemelerinin aşım sayısını nasıl şişirdiğini modelden ölçer'
    - 'Isınma atıldığında iki sürüm arasındaki gerilemenin nasıl göründüğünü gösterir'
    - 'Bütçe gerilemeden geniş seçildiğinde kuralın gerilemeyi göremediğini ayırt eder'
---

# Karşılaştırmalı Ölçüm

Bir işin iki sürümünü karşılaştırmak için ölçümü tekrarlamak gerekir. Ders ısınma yinelemelerinin ölçümü nasıl bozduğunu, atıldıklarında gerilemenin nasıl göründüğünü ve bütçe gerilemeden geniş seçilirse kuralın onu nasıl kaçırdığını ölçer.

Önceki derste istek sayısını bir akış üzerinde bir kez ölçtük ve sonucu kesin kabul ettik. Gerçek bir ölçüm tek bir sayı değildir. Aynı işi arka arkaya çalıştırdığınızda ilk çalıştırmalar sonrakilerden farklı sürer: sınıflar yüklenir, kod derlenir, önbellekler dolar. Bu ilk yinelemelere **ısınma** (warm-up) diyoruz. Ölçüm ısınmayı da kattığında, işin kararlı hâlini değil, kararlı hâle ulaşana kadar geçen yolu ölçer.

Bu dersin sorusu şudur: bir değişikliğin işi yavaşlatıp yavaşlatmadığını, yani bir **gerileme** (regression) olup olmadığını, ısınma ölçümü bozarken nasıl ayırt ederiz. Cevabın iki parçası var: ısınmayı ölçümden ayırmak ve bütçeyi gerilemeyi yakalayacak kadar dar seçmek.

Ölçü yine kursun ölçüsüdür: yinelemelerin bütçeyi kaçında aştığı.

```kotlin
// Overrun.kt — bir olcumun butcesini kac ornekte astigini siniflandirir
class Budget(val name: String, val limit: Int)

class Overrun(val label: String, val budget: Budget, samples: List<Int>) {
    val total: Int = samples.size
    val over: Int = samples.count { it > budget.limit }
    val verdict: String = when {
        over == 0 -> "icinde"
        over == total -> "hepsinde"
        over * 2 < total -> "azinda"
        else -> "cogunda"
    }

    fun line() {
        println("$label: butce=${budget.name}<=${budget.limit} | asan=$over/$total -> $verdict")
    }
}

fun countOverruns(overruns: List<Overrun>) {
    for (name in listOf("icinde", "azinda", "cogunda", "hepsinde")) {
        println("$name: ${overruns.count { it.verdict == name }}")
    }
}
```

`Budget` ölçümün adını ve sınırını taşır, `Overrun` aşan örnekleri sayıp dört aşımdan birini verir. Bu dosya kursun her dersinde aynıdır.

## Yinelemeli Ölçüm Modeli

Modelde bir işin maliyeti iş adımı sayısıdır. İşin iki sürümü var: `eski` ve `yeni`. Yeni sürüm, bir değişiklikten sonra her çalıştırmada üç adım fazla iş yapıyor; bu bizim gerilememiz. Isınma ise ilk yinelemelere eklenen fazladan adımdır ve yinelemeler ilerledikçe azalır.

```kotlin
// Bench.kt — bir isin yinelemeli olcumu; ilk yinelemeler isinma payi tasir
fun workOf(version: String, size: Int): Int = when (version) {
    "eski" -> size * 2
    "yeni" -> size * 2 + 3
    else -> size
}

fun iterations(version: String, size: Int, runs: Int, warmup: Int): List<Int> =
    (0 until runs).map { run ->
        workOf(version, size) + if (run < warmup) (warmup - run) * 4 else 0
    }

fun dropWarmup(samples: List<Int>, warmup: Int): List<Int> = samples.drop(warmup)
```

`workOf` bir sürümün kararlı hâldeki maliyetini verir. `iterations` bu maliyeti `runs` kez yineler ve ilk `warmup` yinelemeye azalan bir ısınma payı ekler. `dropWarmup` ısınma yinelemelerini ölçümden çıkarır. Beş birimlik iş için `eski` sürümün kararlı maliyeti on, `yeni` sürümünki on üçtür. Önce eski sürümü sekiz yinelemeyle, ısınmayı da katarak ölçelim. Bütçe on iki adım olsun.

```kotlin
// Main.kt — eski surum isinma yinelemeleri dahil olculur
fun main() {
    val samples = iterations("eski", 5, 8, 3)
    println("eski: $samples")

    val overrun = Overrun("eski", Budget("adim", 12), samples)
    overrun.line()
    countOverruns(listOf(overrun))
}
```

```text
eski: [22, 18, 14, 10, 10, 10, 10, 10]
eski: butce=adim<=12 | asan=3/8 -> azinda
icinde: 0
azinda: 1
cogunda: 0
hepsinde: 0
```

Sürümün kararlı maliyeti on iki adımlık bütçenin altında, ama ilk üç yineleme ısınma yüzünden aştı: 3/8, **azında**. Eski sürüm bütçeye uygun bir işi yapıyor; ölçüm ise ona üç aşım yazdı. Bu, ısınmanın ölçümü bozmasıdır.

**BA1.** Modelde ısınma payı doğrusal azalır ve yineleme sayısı kesin bilinir. Gerçekte ısınmanın ne zaman bittiği işe, aygıta ve sistemin o anki durumuna bağlıdır; hangi yinelemeden sonra kararlı hâle girildiğini ölçmeden söylemek mümkün değildir. Model her yinelemenin kaç iş adımı yaptığını sayar; yinelemenin ne kadar sürdüğünü kurmaz.

## Isınmayı Atmak ve Gerilemeyi Görmek

Karşılaştırma yapmak için iki sürümü de ısınmayı atarak ölçeriz ve aynı bütçeye vururuz.

```kotlin
// Main.kt — iki surum isinma atilarak ayni butceyle karsilastirilir
fun main() {
    val warmup = 3
    val oldSamples = dropWarmup(iterations("eski", 5, 8, warmup), warmup)
    val newSamples = dropWarmup(iterations("yeni", 5, 8, warmup), warmup)
    println("eski: $oldSamples")
    println("yeni: $newSamples")

    val overruns = listOf(
        Overrun("eski", Budget("adim", 12), oldSamples),
        Overrun("yeni", Budget("adim", 12), newSamples),
    )
    overruns.forEach { it.line() }
    countOverruns(overruns)
}
```

```text
eski: [10, 10, 10, 10, 10]
yeni: [13, 13, 13, 13, 13]
eski: butce=adim<=12 | asan=0/5 -> icinde
yeni: butce=adim<=12 | asan=5/5 -> hepsinde
icinde: 1
azinda: 0
cogunda: 0
hepsinde: 1
```

Isınma atılınca ölçüm temizlendi: eski sürüm **içinde**, yeni sürüm **hepsinde**. Önceki ölçümde eski sürüme yazılan üç aşım ısınmanın payıydı; bu ölçümde ise yeni sürümün beşinin beşinde aşması gerçek bir gerilemeyi gösteriyor. Aradaki fark kararlı hâlde üç adımdır ve bütçe tam bu farkın içinden geçecek şekilde, on iki adımda seçildi.

Platformda bu iki ayrım, ölçümü tekrarlayan bir kural nesnesiyle kurulur. Aşağıdaki parçada ısınma yinelemelerinin sayısı ve ölçülecek yinelemelerin sayısı açıkça verilir.

```kotlin
// Platform kodu: tekrarlanan karsilastirmali olcum
import androidx.benchmark.macro.CompilationMode
import androidx.benchmark.macro.StartupMode
import androidx.benchmark.macro.StartupTimingMetric
import androidx.benchmark.macro.junit4.MacrobenchmarkRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class StartupBenchmark {
    @get:Rule
    val benchmarkRule = MacrobenchmarkRule()

    @Test
    fun coldStartup() = benchmarkRule.measureRepeated(
        packageName = "com.example.app",
        metrics = listOf(StartupTimingMetric()),
        iterations = 5,
        startupMode = StartupMode.COLD,
        compilationMode = CompilationMode.Partial(warmupIterations = 3),
    ) {
        pressHome()
        startActivityAndWait()
    }
}
```

Bu parça platform kodudur ve burada çıktı, süre ya da oran iddia etmiyoruz. Kural nesnesi `measureRepeated` ile ölçümü beş kez yineler ve ısınma yinelemelerini ayrıca belirtilen sayıda çalıştırır; hangi sürelerin çıkacağı aygıta ve uygulamaya bağlıdır. Model, bu ölçümün kuralını kurar; model aracın kendisi değildir. Aracın ısınmayı ne zaman bitmiş saydığı, modelin göstermediği bilgidir.

## Yineleme Sayısı Ölçümü Değiştirir

Isınma atılmazsa, aşım sayısı yineleme sayısına da bağlıdır, çünkü ısınma payı sabittir ve yineleme sayısı arttıkça payı küçülür. Aynı eski sürümü, ısınmayı katarak, dört, sekiz ve on altı yinelemeyle ölçelim.

```kotlin
// Main.kt — ayni surum isinma dahil uc farkli yineleme sayisiyla olculur
fun main() {
    val overruns = listOf(4, 8, 16).map { runs ->
        Overrun("yineleme-$runs", Budget("adim", 12), iterations("eski", 5, runs, 3))
    }
    overruns.forEach { it.line() }
    countOverruns(overruns)
}
```

```text
yineleme-4: butce=adim<=12 | asan=3/4 -> cogunda
yineleme-8: butce=adim<=12 | asan=3/8 -> azinda
yineleme-16: butce=adim<=12 | asan=3/16 -> azinda
icinde: 0
azinda: 2
cogunda: 1
hepsinde: 0
```

Sürüm aynı, ısınma aynı, aşan yineleme sayısı üç. Yalnız yineleme sayısı değişti ve aşım çoğundan azına geçti. Bu yüzden ısınma dahil edilen bir ölçümde sonucu yinelemeler belirler; ısınma atılan bir ölçümde ise kararlı hâl belirler. Karşılaştırmalı ölçümün güvenilir olması için ikisi birlikte sabitlenir: kaç yineleme ölçülecek ve kaçı ısınma sayılıp atılacak.

## Mikro ve Makro Karşılaştırmalı Ölçüm

Karşılaştırmalı ölçüm iki düzeyde yapılır. Mikro düzeyde tek bir işlev ya da küçük bir kod parçası, yalıtılmış bir ortamda tekrar tekrar çalıştırılır; amaç o parçanın maliyetini diğer işlerden ayırmaktır. Makro düzeyde uygulamanın bir akışı, örneğin başlatma ya da bir ekranın açılması, uçtan uca ölçülür; amaç kullanıcının yaşadığı sonucu görmektir.

İkisi birbirinin yerine geçmez. Mikro ölçüm iyileşmiş görünürken makro ölçüm aynı kalabilir, çünkü ölçülen parça akışın küçük bir bölümüdür. Makro ölçüm gerilemeyi gösterirken mikro ölçüm temiz çıkabilir, çünkü sorun parçaların etkileşimindedir. Bu derste model tek bir iş birimini ölçer; gerçek bir proje iki düzeyi de kullanır.

## Temel Değer

Gerilemeyi yakalamak için bir karşılaştırma noktası gerekir. Bu nokta, işin kabul edilmiş sürümünün ölçümüdür ve **temel değer** (baseline) olarak saklanır. Yeni ölçüm bu değerle karşılaştırılır; fark belirli bir sınırı aşarsa gerileme sayılır. Dersin modelinde temel değer, eski sürümün kararlı hâldeki maliyetidir.

Temel değerin kendisi bir ölçümdür ve ısınma ile gürültüden etkilenir. Temel değeri ısınma dahil almak, tüm sonraki karşılaştırmaları bozar. Temel değer bu yüzden yalnız kararlı yinelemelerden hesaplanır ve ölçüldüğü koşullarla birlikte kaydedilir.

## Isınma Neden Vardır

Isınma, işin ilk çalıştırmalarının sonrakilerden pahalı olmasıdır. İlk çalıştırmada kod henüz derlenmemiş olabilir, ön bellekler boştur, kullanılan kaynaklar ilk kez açılır. Birkaç yinelemeden sonra bu maliyetler ödenmiş olur ve iş kararlı hâline varır. Modelde ısınma, ilk yinelemelere eklenen ve azalan bir paydır; gerçek ısınmanın şekli işe göre değişir.

Isınmayı ölçümden atmak kararlı hâli ölçmeyi seçmektir. Bu seçim doğrudur, çünkü bir gerilemeyi yakalamak için işin kendisi ölçülmeli, ilk çalıştırma şansı değil. Ama ısınmayı atan bir ölçüm kullanıcının ilk karşılaştığı maliyeti görmez. Bu yüzden başlangıcı ölçen bir ölçüm ile gerilemeyi ölçen bir ölçüm ayrı tutulur: ilkinde ısınma ölçümün konusudur, ikincisinde gürültüdür.

## Ölçüm Düzeneği Sabit Kalmalı

Karşılaştırmalı ölçümde iki sürüm yan yana değil, aynı düzenekte art arda ölçülür. Düzenek değişirse, örneğin bir ölçüm başka bir aygıtta ya da başka bir sistem durumunda alınırsa, fark gerilemeden değil düzenekten gelebilir. Bu derste düzenek modelin kendisidir ve her ölçümde aynıdır; gerçek bir projede aynı güvence ancak aygıtı, sistem durumunu ve yineleme sayısını sabitleyerek sağlanır.

Bu sabitlik ölçüm sonuçlarının nasıl saklanacağını da belirler. Bir temel değer kaydedilirken, hangi sürümde, kaç yinelemeyle ve ısınma atılarak mı atılmadan mı alındığı yanına yazılır. Bu bilgi olmadan iki sayı karşılaştırılamaz; çünkü ders, aynı sürümün yineleme sayısına göre iki farklı aşım verebildiğini gösterdi.

Bütçenin nereden geldiği de sorulmalıdır. Bu derste on iki adım, eski sürümün kararlı maliyeti olan on ile yeni sürümün maliyeti olan on üç arasına yerleştirildi ve hangi sürümün içinde kalacağını baştan belirledi. Gerçek bir projede bütçe, kabul edilmiş sürümün ölçümüne küçük bir pay eklenerek konur; pay gürültünün genişliğinden büyük, gerilemenin büyüklüğünden küçük olmalıdır. Pay çok büyükse kural gerilemeyi göremez, çok küçükse her ölçümde yanlış alarm verir.

Sonuçları raporlarken tek bir sayı yerine sayıların dağılımı verilir: en iyi yineleme, en kötü yineleme ve ortadaki. Bu derste yineleme başına iş adımı sayısı örneklerin kendisidir ve her ölçümün altında yazdırılır. Kuralın yazdığı tek satır aşım sayısını özetler; örnekler okunduğunda ise ısınmanın nerede bittiği ve gerilemenin nerede başladığı görülür.

Karşılaştırmalı ölçüm sonucunda alınan karar da yazılı olmalıdır. Bir değişiklik gerileme çıkardıysa üç yol vardır: değişikliği geri almak, gerilemeyi kabul edip temel değeri yükseltmek ya da gerilemeyi başka bir yerde telafi etmek. Hangisinin seçildiği ve nedeni kayda geçmezse, sonraki ölçüm yeni temel değerin neden öyle olduğunu açıklayamaz. Bu derste üç adımlık fark açıkça bir gerilemeydi; ürün kararı onu kabul etmek ya da etmemek arasındadır ve bunu kural vermez.

Yinelemelerin sırası da bilgi taşır. Isınma payı ilk yinelemelerde yoğunlaştığından, örnek dizisinin başı sonundan farklı bir şey ölçer. Diziyi karıştırıp ortalamasını almak ısınmayı kararlı hâle karıştırır ve iki ayrı olguyu tek sayıda birleştirir. Sıralı yazdırılan örnekler, ısınmanın bittiği yinelemeyi göz kararı olmadan gösterir ve atılacak yineleme sayısını seçmenin dayanağı olur.

## Yaygın Yanılgılar

**"Bir kez ölçmek yeter."** Tek ölçüm, ısınmayı ve gürültüyü ayıramaz. Ders bunu, aynı sürümün yineleme sayısına göre farklı aşım vermesiyle gösterdi.

**"Isınmayı atmak ölçümü güzelleştirir."** Isınma atılırken ölçümün neyi hedeflediği belli olmalıdır. Kullanıcı uygulamayı ilk kez açtığında ısınma maliyetini öder; bu maliyeti ölçmek isteyen bir ölçüm, ısınmayı atmaz, onu ayrı bir ölçüm olarak alır.

**"Küçük fark gerilemedir."** Gürültü varken küçük bir fark, gerilemeden de gelebilir. Bu derste model gürültüsüzdür, bu yüzden üç adımlık fark kesindir. Gerçek ölçümde farkın gürültüden büyük olduğundan emin olmak için yinelemeler çoğaltılır.

**"Kural gerilemeyi bulur."** Kural yalnız bütçeyi aşan örnekleri sayar. Bütçe gerilemenin üstündeyse kural gerilemeyi göremez; dersin sınırlayıcı ölçümü bunu gösterdi.

## Sınırlayıcı Ölçüm

Kuralın en önemli sınırı şudur: bütçe gerilemeden geniş seçilirse kural gerilemeyi göremez. İki sınamayla gösterelim. Birincisinde ısınma dahil, bütçe yirmi adım. İkincisinde ısınma atılmış, bütçe on üç adım.

```kotlin
// Main.kt — genis butcede gerileme kuralin gozunden kacar
fun main() {
    val warmup = 3
    val oldAll = iterations("eski", 5, 8, warmup)
    val newAll = iterations("yeni", 5, 8, warmup)
    val oldSteady = dropWarmup(oldAll, warmup)
    val newSteady = dropWarmup(newAll, warmup)

    val overruns = listOf(
        Overrun("eski-isinmali", Budget("adim", 20), oldAll),
        Overrun("yeni-isinmali", Budget("adim", 20), newAll),
        Overrun("eski-kararli", Budget("adim", 13), oldSteady),
        Overrun("yeni-kararli", Budget("adim", 13), newSteady),
    )
    overruns.forEach { it.line() }
    countOverruns(overruns)
}
```

```text
eski-isinmali: butce=adim<=20 | asan=1/8 -> azinda
yeni-isinmali: butce=adim<=20 | asan=2/8 -> azinda
eski-kararli: butce=adim<=13 | asan=0/5 -> icinde
yeni-kararli: butce=adim<=13 | asan=0/5 -> icinde
icinde: 2
azinda: 2
cogunda: 0
hepsinde: 0
```

Yirmi adımlık bütçede iki sürüm de **azında**; on üç adımlık bütçede ikisi de **içinde**. Yeni sürüm üç adım yavaşlamış olmasına karşın kural, iki durumda da iki sürüme aynı aşımı yazdı. İsınmalı ölçümde yeni sürümün aşan yineleme sayısı iki, eski sürümünki bir: fark bir yinelemedir ve yalnız örnek sayısına bakarak gerilemeden mi, ısınmadan mı geldiği ayırt edilemez. Isınması atılmış ölçümde ise on üç adım, yeni sürümün tam sınırıdır ve sınıra eşit örnek aşım sayılmaz. Kural aşımın sayısını görür; büyüklüğünü, yani üç adımlık farkı, görmez. Aynı işlev iki bütçede iki aşım verebilir; bütçe gerilemenin altında kalan bir değere konmazsa gerileme kuralın içinde kalır.

**BA2.** Modeldeki gerileme, her yinelemede aynı üç adımdır. Gerçek gerilemeler her yinelemede aynı gelmez; bazıları yalnız belirli girdilerde ya da belirli aygıtlarda ortaya çıkar. Tek bir ölçüm düzeneğinde görünmeyen bir gerilemenin başka düzenekte görünmeyeceği sonucuna varılamaz.

## Özet

- Bu dersin aşımı: azında. Eski sürümün kararlı maliyeti bütçeyi aşmadı, ama ilk üç ısınma yinelemesi aştı ve sekiz yinelemenin üçü bütçeyi geçti.
- Isınma yinelemeleri işin kararlı hâlini değil, kararlı hâle ulaşma yolunu ölçer. Karşılaştırma için ısınma ölçümden atılır.
- Isınma atılınca eski sürüm içinde, yeni sürüm hepsinde çıktı; üç adımlık gerileme görünür oldu.
- Isınma dahil ölçümde aynı sürüm, yineleme sayısına göre çoğunda ya da azında çıktı.
- Bütçe gerilemeden geniş seçilirse kural iki sürüme aynı aşımı yazar: aşımın sayısını görür, büyüklüğünü görmez.

## Sonraki Adım

Bu ders ölçümün neyi ölçtüğünü sabitledi. Geriye ölçülen şeyin yayımlanacak pakete nasıl girdiği kalıyor. Sıradaki ders, `Küçültme ve Karartma`, uygulama paketinden kullanılmayan sınıfları ayıklarken koruma kurallarının hangi sınıfları ayakta tuttuğunu ve geniş bir kuralın küçültmeyi nasıl boşa çıkardığını ölçer.
