IlmHamroh
Python kursi/Miqyos va unumdorlik1/10-dars19 daqiqa
Mundarija (22)

29.1-dars: Unumdorlikni o'lchash

29-QISM — MIQYOS VA UNUMDORLIK · 1-dars


1. Kirish va motivatsiya

"Bu kod sekin" — lekin qanchalik sekin? Qayerda sekin? Nima uchun sekin? Bu savollarga o'lchamasdan javob berib bo'lmaydi. Dasturchilar ko'pincha taxmin qiladi ("bu funksiya sekin bo'lsa kerak") va noto'g'ri joyni optimallashtiradi (haqiqiy muammo boshqa joyda). Yoki umuman o'lchamasdan optimallashtiradi (erta optimizatsiya — 28.4). Unumdorlikni o'lchash — dastur tezligini raqamlar bilan aniqlash: qancha vaqt oladi (latency), qancha ish bajaradi (throughput), qancha resurs ishlatadi. O'lchash — optimizatsiyaning birinchi qadami: "o'lchamasang — yaxshilay olmaysan".

Unumdorlikni o'lchash — dastur ishlash ko'rsatkichlarini aniqlash: latency (kechikish — bir amal qancha vaqt oladi: javob vaqti), throughput (o'tkazuvchanlik — vaqt birligida qancha ish: soniyada so'rovlar), resurs (CPU, xotira, disk), murakkablik (Big-O — kirish o'sganda qanday o'sadi). Usullar: timing (vaqt o'lchash — time.perf_counter), benchmark (takroriy o'lchash — barqaror natija), amal sanash (operatsiyalar soni — deterministik), Big-O tahlili (nazariy o'sish). Prinsip: avval o'lcha, keyin optimallashtir 28.4-bob. Bu profiling 29.2-bob uchun asos. Unumdorlikni o'lchash — tezlikni raqamlashtirish. O'lchash — optimizatsiya asosi.

Real vaziyat. Bir tizim sekinlashdi — dasturchi baza so'rovini optimallashtirmoqchi edi (taxmin). O'lchash qilindi: latency o'lchandi, throughput sanaldi — ma'lum bo'ldi, muammo bazada emas, N+1 so'rov (13-qism kabi — har element uchun alohida so'rov, O(n) so'rov). Kod tuzatildi (bir so'rov — O(1)), 50 barobar tez bo'ldi. Taxmin noto'g'ri edi, o'lchash haqiqatni ko'rsatdi. Unumdorlikni o'lchash — to'g'ri muammoni topdi.

Bu darsda unumdorlikni o'lchashni o'rganamiz.

Bu darsda:

  • Nega o'lchash (taxmin emas)
  • Latency va throughput
  • Big-O murakkablik
  • Amallarni sanash (deterministik)
  • Timing va benchmark
  • Nima o'lchash (nima muhim)
  • O'lchash tuzoqlari
  • Amaliy: o'lchash modeli

ℹ Misollar amal sonini (deterministik) o'lchaydi — vaqt emas (vaqt o'zgaruvchan).


2. Nazariya — chuqur tushuntirish

2.1. Nega o'lchash (taxmin emas)

Taxmin adashtiradi:

Taxmin: "bu funksiya sekin" (intuitsiya) → noto'g'ri joyni tuzatish
O'lchash: raqamlar (qayerda, qancha) → to'g'ri muammo

"o'lchamasang — yaxshilay olmaysan"

Nega o'lchash — unumdorlik intuitsiyaga ishonib bo'lmaydi (taxmin ko'pincha noto'g'ri — dasturchi bir joyni sekin deb o'ylaydi, haqiqiy muammo boshqa joyda): o'lchash raqamlar beradi (qayerda sekin, qancha). Sabab: optimizatsiya vaqt oladi — o'lchamasdan noto'g'ri joyga sarflanadi (28.4 — 80/20); o'lchash to'g'ri muammoni topadi (eng katta ta'sir). "O'lchamasang — yaxshilay olmaysan" (o'lchov — yaxshilanish asosi). Bu erta optimizatsiya 28.4-bob ga qarshi. O'lchash — haqiqatga asoslangan optimizatsiya. Raqam — taxmin emas.

2.2. Latency va throughput

Ikki asosiy o'lchov:

LATENCY (kechikish) — bir amal qancha vaqt
   masalan: bir so'rov 200ms (foydalanuvchi kutadi)

THROUGHPUT (o'tkazuvchanlik) — vaqt birligida qancha ish
   masalan: soniyada 1000 so'rov (tizim sig'imi)

farqli: tez javob (latency) vs ko'p ish (throughput)

Latency va throughput — ikki asosiy unumdorlik o'lchovi: Latency (kechikish) — bir amal qancha vaqt oladi (bir so'rov 200ms — foydalanuvchi kutadi; javob vaqti); Throughput (o'tkazuvchanlik) — vaqt birligida qancha ish bajariladi (soniyada 1000 so'rov — tizim sig'imi). Ular farqli (ba'zan qarama-qarshi): tez javob (past latency) vs ko'p ish (yuqori throughput) — masalan navbat throughputni oshiradi, lekin latencyni (kutish). Foydalanuvchi latencyni his qiladi 28.10-bob, tizim throughputga muhtoj (yuk). Ikkalasi muhim. Latency — tezlik, throughput — sig'im. Bir amal vs ko'p amal.

2.3. Big-O murakkablik

Kirish o'sganda qanday o'sadi:

Big-O — kirish (n) o'sganda ishning o'sishi:
   O(1) — doimiy (n ta'sir qilmaydi) — eng yaxshi
   O(log n) — logarifmik (juda sekin o'sadi)
   O(n) — chiziqli (n ga mutanosib)
   O(n^2) — kvadratik (n^2 — tez o'sadi, yomon)

Big-O murakkablik — algoritm ishlash vaqti kirish hajmi (n) o'sganda qanday o'sishini tavsiflaydi (nazariy — 08-qism): O(1) (doimiy — n ta'sir qilmaydi, eng yaxshi — lug'at qidiruvi), O(log n) (logarifmik — juda sekin, ikkilik qidiruv), O(n) (chiziqli — n ga mutanosib, ro'yxat aylanish), O(n log n) (saralash), O(n^2) (kvadratik — ichma-ich sikl, tez o'sadi — yomon), O(2^n) (eksponensial — halokat). Sabab: kichik n'da farq ko'rinmaydi (100 element), katta n'da halokat (million — O(n^2) soatlar). Big-O — miqyoslanuvchanlik (katta yukda qanday). Big-O — o'sish tezligi. Kirish o'sganda — qanday o'sadi.

2.4. Amallarni sanash (deterministik)

Vaqt o'rniga amal:

python
# vaqt o'zgaruvchan (mashina, yuk) — deterministik emas
# amal soni — deterministik (bir xil kirish → bir xil son)

amallar = 0
for x in royxat:        # n amal
    amallar += 1
# O(n): amallar = len(royxat)

Amallarni sanash — unumdorlikni deterministik o'lchash usuli: haqiqiy vaqt o'zgaruvchan (mashina, yuk, keshga bog'liq — har safar boshqacha), lekin amallar soni deterministik (bir xil kirish → bir xil son). Masalan for x in royxat — len(royxat) amal (O(n)); ichma-ich sikl — n^2 amal (O(n^2)). Sabab: amal sanash Big-O ni ko'rsatadi (o'sish naqshi), vaqtga bog'liq emas (o'qitish, taqqoslash uchun aniq). Bu kurs uslubi (deterministik natijalar). Amal sanash — Big-O ni amalda ko'rish. Amal soni — barqaror o'lchov.

2.5. Timing va benchmark

Haqiqiy vaqt o'lchash:

python
import time
boshlanish = time.perf_counter()
funksiya()
vaqt = time.perf_counter() - boshlanish   # sekundlar

# benchmark: ko'p marta (barqaror natija)
import timeit
timeit.timeit(funksiya, number=1000)   # 1000 marta o'rtacha

Timing va benchmark — haqiqiy vaqt o'lchash: timing (time.perf_counter — yuqori aniqlikda vaqt, boshlanish-tugash farqi); benchmark (timeit — funksiyani ko'p marta ishga tushirib o'rtacha — bir marta o'lchov shovqinli: kesh, tizim yuki). Muhim: bir marta o'lchash ishonchsiz (o'zgaruvchan — 28.10 persentil kabi), ko'p marta barqaror. Ehtiyot: benchmark real sharoitni aks ettirmasligi mumkin (kichik ma'lumot, kesh isigan). Timing — real vaqt (lekin o'zgaruvchan). Amal sanash — Big-O; timing — real tezlik. Vaqt — real, lekin shovqinli.

2.6. Nima o'lchash (nima muhim)

Nima o'lchash — hamma narsani emas, muhimni: foydalanuvchi his qiladigan (latency — javob vaqti, 28.10 RED), eng ko'p ishlaydigan (issiq yo'l — hot path, ko'p chaqiriladigan kod), miqyoslanuvchi (katta yukda — Big-O), resurs cheklovi (xotira, CPU — nima tugaydi). O'lchov: oxirdan (foydalanuvchi tajribasi — end-to-end) va ichki (funksiya darajasida — profiling 29.2). Sabab: hamma narsani o'lchash — shovqin; muhim (eng ko'p ta'sir) — foydali. Bu 28.10 (RED/USE — muhim metrikalar) bilan mos. Nima o'lchash — muhim ko'rsatkichlar. Foydalanuvchi va issiq yo'l.

2.7. O'lchash tuzoqlari

O'lchash tuzoqlari: bir marta o'lchash (shovqinli — ko'p marta, o'rtacha/persentil — 28.10); noto'g'ri sharoit (kichik ma'lumot — katta ma'lumot boshqacha; kesh isigan — sovuq boshqacha); Big-O ni e'tiborsiz (kichik n'da tez, katta n'da halokat — miqyos); mikro-optimizatsiya (kichik joyni optimallashtirish — umumiyga ta'sir kam, 28.4 — o'lcha avval); o'lchov ta'siri (o'lchash o'zi sekinlashtiradi — observer effect); taxminga qaytish (o'lchamasdan "bilaman"). Yaxshi o'lchash: ko'p marta, real sharoit, muhim joy, Big-O bilan. Tuzoq — noto'g'ri o'lchov (noto'g'ri xulosa). O'lchash ham to'g'ri qilinishi kerak.

2.8. O'lchash — optimizatsiyaning asosi

Unumdorlikni o'lchash — optimizatsiyaning asosi: "o'lcha → tahlil qil → optimallashtir → qayta o'lcha" (ilmiy usul — gipoteza, sinov). O'lchamasdan optimizatsiya — ko'r (28.4 — noto'g'ri joy, mikro-optimizatsiya). O'lchash haqiqatni ko'rsatadi (taxmin emas): qayerda sekin (profiling — 29.2), qanchalik (latency/throughput), nega (Big-O, resurs). Bu kesh 29.3-bob, navbat 29.4-bob, miqyoslash 29.6-bob — barcha optimizatsiya qarorlarining asosi. "O'lchamasang — yaxshilay olmaysan" — muhandislik prinsipi. O'lchash — bilishning yo'li (taxmin emas). Raqam — optimizatsiya kompasi.


3. Tez ma'lumotnoma

python
# O'LCHOVLAR:
# Latency — bir amal vaqti (javob vaqti)
# Throughput — vaqt birligida ish (soniyada so'rov)
# Big-O — kirish o'sganda o'sish (O(1), O(n), O(n^2))

# AMAL SANASH (deterministik):
amallar = 0
for x in data: amallar += 1          # O(n)
for x in data:
    for y in data: amallar += 1      # O(n^2)

# TIMING (real, o'zgaruvchan):
import time
t = time.perf_counter(); f(); vaqt = time.perf_counter() - t

# BENCHMARK (barqaror):
import timeit
timeit.timeit(f, number=1000)        # ko'p marta o'rtacha

# BIG-O:
# O(1) doimiy · O(log n) · O(n) chiziqli · O(n^2) kvadratik

# PRINSIP: avval o'lcha, keyin optimallashtir (28.4)
# NIMA: latency (foydalanuvchi), issiq yo'l, Big-O

Unumdorlikni o'lchash xulosasi

O'lchash — tezlikni raqamlashtirish (taxmin emas)
Latency (bir amal) · throughput (vaqt birligida ish)
Big-O (kirish o'sganda o'sish — O(1), O(n), O(n^2))
Amal sanash (deterministik) · timing/benchmark (real)
Avval o'lcha, keyin optimallashtir · muhimni o'lcha

4. Batafsil misollar

Misollar amal sonini (deterministik) o'lchaydi — vaqt emas (vaqt o'zgaruvchan).

Misol 1 — Big-O: amallarni sanash

python
"""Big-O: turli algoritmlarda amallar soni (kirish o'sganda o'sish)."""


def olchash_O1(data: list) -> int:
    # O(1) — doimiy (birinchi element)
    amallar = 0
    if data:
        _ = data[0]
        amallar += 1
    return amallar


def olchash_On(data: list) -> int:
    # O(n) — har element
    amallar = 0
    for _ in data:
        amallar += 1
    return amallar


def olchash_On2(data: list) -> int:
    # O(n^2) — ichma-ich
    amallar = 0
    for _ in data:
        for _ in data:
            amallar += 1
    return amallar


def main() -> None:
    print("=== 1. O(1) — doimiy ===")
    for n in [10, 100, 1000]:
        print(f"  n={n}: {olchash_O1(list(range(n)))} amal (o'zgarmaydi)")

    print("\n=== 2. O(n) — chiziqli ===")
    for n in [10, 100, 1000]:
        print(f"  n={n}: {olchash_On(list(range(n)))} amal (n ga teng)")

    print("\n=== 3. O(n^2) — kvadratik ===")
    for n in [10, 100]:
        print(f"  n={n}: {olchash_On2(list(range(n)))} amal (n^2)")

    print("\n=== 4. Farqi (n=1000) ===")
    print(f"  O(1): 1, O(n): 1000, O(n^2): 1,000,000")
    print("  katta n'da O(n^2) halokat (miqyoslanmaydi)")
    print("  ⭐ Big-O — kirish o'sganda o'sish")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. O(1) — doimiy ===
  n=10: 1 amal (o'zgarmaydi)
  n=100: 1 amal (o'zgarmaydi)
  n=1000: 1 amal (o'zgarmaydi)

=== 2. O(n) — chiziqli ===
  n=10: 10 amal (n ga teng)
  n=100: 100 amal (n ga teng)
  n=1000: 1000 amal (n ga teng)

=== 3. O(n^2) — kvadratik ===
  n=10: 100 amal (n^2)
  n=100: 10000 amal (n^2)

=== 4. Farqi (n=1000) ===
  O(1): 1, O(n): 1000, O(n^2): 1,000,000
  katta n'da O(n^2) halokat (miqyoslanmaydi)
  ⭐ Big-O — kirish o'sganda o'sish

Nima ko'rsatdi: 2.3, 2.4-bo'limlar.

Misol 2 — Sekin va tez algoritm (amal farqi)

python
"""Amal farqi: O(n^2) va O(n) yechim — bir vazifa, turli tezlik."""


def takroriy_izlash(data: list, qidiruvlar: list) -> dict:
    # O(n*m) — har qidiruv uchun butun ro'yxatni aylanish
    amallar = 0
    natija = []
    for q in qidiruvlar:
        topildi = False
        for x in data:
            amallar += 1
            if x == q:
                topildi = True
                break
        natija.append(topildi)
    return {"amallar": amallar, "natija": natija}


def tez_izlash(data: list, qidiruvlar: list) -> dict:
    # O(n+m) — set (O(1) qidiruv)
    amallar = 0
    tuplam = set(data)   # O(n) qurish
    amallar += len(data)
    natija = []
    for q in qidiruvlar:
        amallar += 1     # O(1) qidiruv
        natija.append(q in tuplam)
    return {"amallar": amallar, "natija": natija}


def main() -> None:
    data = list(range(100))
    qidiruvlar = [50, 99, 150, 25]

    print("=== 1. Takroriy izlash (O(n*m)) ===")
    r1 = takroriy_izlash(data, qidiruvlar)
    print(f"  amallar: {r1['amallar']}")
    print(f"  natija: {r1['natija']}")

    print("\n=== 2. Set bilan izlash (O(n+m)) ===")
    r2 = tez_izlash(data, qidiruvlar)
    print(f"  amallar: {r2['amallar']}")
    print(f"  natija: {r2['natija']}")

    print("\n=== 3. Bir xil natija ===")
    print(f"  teng: {r1['natija'] == r2['natija']}")

    print("\n=== 4. Amal farqi ===")
    print(f"  takroriy: {r1['amallar']}, set: {r2['amallar']}")
    print("  set — O(1) qidiruv (list — O(n))")
    print("  ⭐ To'g'ri struktura — kam amal (tez)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Takroriy izlash (O(n*m)) ===
  amallar: 277
  natija: [True, True, False, True]

=== 2. Set bilan izlash (O(n+m)) ===
  amallar: 104
  natija: [True, True, False, True]

=== 3. Bir xil natija ===
  teng: True

=== 4. Amal farqi ===
  takroriy: 277, set: 104
  set — O(1) qidiruv (list — O(n))
  ⭐ To'g'ri struktura — kam amal (tez)

Nima ko'rsatdi: 2.1, 2.4-bo'limlar.

Misol 3 — Latency va throughput modeli

python
"""Latency va throughput: bir amal vaqti vs vaqt birligida ish."""


def latency_throughput(bir_amal_ms: float, parallel: int) -> dict:
    # latency — bir amal (o'zgarmaydi parallelda)
    latency = bir_amal_ms
    # throughput — soniyada amallar (parallel bilan oshadi)
    throughput = (1000 / bir_amal_ms) * parallel
    return {"latency_ms": latency, "throughput_sek": round(throughput)}


def main() -> None:
    print("=== 1. Bir ishchi (1 parallel) ===")
    r = latency_throughput(bir_amal_ms=100, parallel=1)
    print(f"  latency: {r['latency_ms']}ms (bir so'rov)")
    print(f"  throughput: {r['throughput_sek']} so'rov/sek")

    print("\n=== 2. 4 ishchi (parallel) ===")
    r = latency_throughput(bir_amal_ms=100, parallel=4)
    print(f"  latency: {r['latency_ms']}ms (o'zgarmadi!)")
    print(f"  throughput: {r['throughput_sek']} so'rov/sek (4x)")

    print("\n=== 3. Farq ===")
    print("  latency — bir amal (parallel ta'sir qilmaydi)")
    print("  throughput — ko'p amal (parallel oshiradi)")

    print("\n=== 4. Qaysi muhim ===")
    print("  foydalanuvchi — latency (kutish)")
    print("  tizim sig'imi — throughput (yuk)")
    print("  ⭐ Latency vs throughput — tezlik vs sig'im")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Bir ishchi (1 parallel) ===
  latency: 100ms (bir so'rov)
  throughput: 10 so'rov/sek

=== 2. 4 ishchi (parallel) ===
  latency: 100ms (o'zgarmadi!)
  throughput: 40 so'rov/sek (4x)

=== 3. Farq ===
  latency — bir amal (parallel ta'sir qilmaydi)
  throughput — ko'p amal (parallel oshiradi)

=== 4. Qaysi muhim ===
  foydalanuvchi — latency (kutish)
  tizim sig'imi — throughput (yuk)
  ⭐ Latency vs throughput — tezlik vs sig'im

Nima ko'rsatdi: 2.2-bo'lim.

Misol 4 — O'lchash → tahlil → optimallashtirish

python
"""O'lchash sikli: o'lcha → eng katta ta'sirni top → optimallashtir."""


def profil(qadamlar: dict) -> dict:
    jami = sum(qadamlar.values())
    eng_ogir = max(qadamlar, key=lambda q: qadamlar[q])
    return {"jami": jami, "eng_ogir": eng_ogir, "eng_ogir_foiz": round(qadamlar[eng_ogir] / jami * 100)}


def main() -> None:
    # o'lchangan qadamlar (amal soni)
    qadamlar = {"kirish_oqish": 50, "baza_sorov": 800, "hisoblash": 100, "javob": 50}

    print("=== 1. O'lchangan qadamlar (amal) ===")
    for qadam, amal in qadamlar.items():
        print(f"  {qadam}: {amal}")

    print("\n=== 2. Tahlil ===")
    p = profil(qadamlar)
    print(f"  jami: {p['jami']} amal")
    print(f"  eng og'ir: {p['eng_ogir']} ({p['eng_ogir_foiz']}%)")

    print("\n=== 3. Qayerni optimallashtirish ===")
    print(f"  {p['eng_ogir']} — eng katta ta'sir (bu yerdan)")
    print("  boshqa qadamlarni optimallashtirish — kam foyda")

    print("\n=== 4. Optimallashtirishdan keyin (baza 800→100) ===")
    yangi = {**qadamlar, "baza_sorov": 100}
    p2 = profil(yangi)
    print(f"  yangi jami: {p2['jami']} amal (avval {p['jami']})")
    print(f"  tejaladi: {p['jami'] - p2['jami']} amal")
    print("  ⭐ O'lcha → eng katta ta'sirni tuzat 28.4-bob")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. O'lchangan qadamlar (amal) ===
  kirish_oqish: 50
  baza_sorov: 800
  hisoblash: 100
  javob: 50

=== 2. Tahlil ===
  jami: 1000 amal
  eng og'ir: baza_sorov (80%)

=== 3. Qayerni optimallashtirish ===
  baza_sorov — eng katta ta'sir (bu yerdan)
  boshqa qadamlarni optimallashtirish — kam foyda

=== 4. Optimallashtirishdan keyin (baza 800→100) ===
  yangi jami: 300 amal (avval 1000)
  tejaladi: 700 amal
  ⭐ O'lcha → eng katta ta'sirni tuzat (28.4)

Nima ko'rsatdi: 2.7, 2.8-bo'limlar.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"Taxmin yetadi" O'lchash (taxmin adashtiradi)
"Latency = throughput" Bir amal vs ko'p amal
"Big-O ahamiyatsiz" Katta n'da halokat
"Bir marta o'lchash" Ko'p marta (barqaror)
"Kichik ma'lumot yetadi" Real sharoit (katta)
"Vaqt deterministik" O'zgaruvchan (amal — barqaror)
"Hamma narsani o'lcha" Muhim (issiq yo'l)
"O'lchash keraksiz" Optimizatsiya asosi

6. Keng tarqalgan xatolar va yechimlari

1. O'lchamasdan optimallashtirish

python
# "bu sekin bo'lsa kerak" (taxmin)                # ⚠️
# o'lcha → eng katta ta'sirni top 28.4-bob           # ✅

2. Bir marta o'lchash

python
t = timeit(f, number=1)   # shovqinli             # ⚠️
timeit(f, number=1000)   # ko'p marta (barqaror)   # ✅

3. Big-O ni e'tiborsiz

python
for x in a:
    for y in a: ...   # O(n^2) (katta n — halokat)   # ⚠️
set/dict (O(1) qidiruv)                             # ✅

4. Kichik ma'lumot bilan sinash

python
# 100 element bilan test (prod — million)          # ⚠️
# real hajm (katta ma'lumot)                         # ✅

5. Mikro-optimizatsiya (o'lchamasdan)

python
# kichik joyni optimallashtirish (umumga kam)       # ⚠️
# o'lcha → eng katta ta'sir                          # ✅

6. Latency/throughput aralashtirish

python
# "tez" — qaysi (latency yoki throughput?)          # ⚠️
# aniq (bir amal vaqti yoki sig'im?)                 # ✅

7. Sovuq/issiq kesh farqi

python
# birinchi o'lchov (sovuq — sekin)                  # ⚠️
# isitib, keyin o'lcha (yoki ikkalasini)             # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 29.2-dars: Profiling — qayerda sekin
  • 29.3-dars: Kesh — o'lchov asosida
  • 08-qism (o'tilgan): Algoritmlar — Big-O
  • 28.10-dars (o'tilgan): Monitoring — prodda latency
  • 28.4-dars (o'tilgan): Optimizatsiya — o'lcha avval

8. Eng yaxshi amaliyotlar

  1. Avval o'lcha (taxmin emas).

  2. Ko'p marta (benchmark — barqaror).

  3. Big-O bilan (katta n miqyos).

  4. Real sharoit (katta ma'lumot).

  5. Muhimni o'lcha (issiq yo'l, latency).

  6. Latency/throughput ajrat (tezlik vs sig'im).

  7. Amal sanash (deterministik tahlil).

  8. O'lcha → tuzat → qayta o'lcha (sikl).


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # nega o'lchash (taxmin emas)?
2.  # latency nima?
3.  # throughput nima?
4.  # latency vs throughput?
5.  # Big-O nima?
6.  # O(1) vs O(n^2)?
7.  # amal sanash nega?
8.  # timing nima?
9.  # benchmark nega ko'p marta?
10. # nima o'lchash?
11. # issiq yo'l nima?
12. # o'lchash tuzog'i?
Javoblar
  1. Taxmin adashtiradi (raqam — haqiqat)
  2. Bir amal vaqti (javob vaqti)
  3. Vaqt birligida ish (soniyada so'rov)
  4. Bir amal (tezlik) vs ko'p amal (sig'im)
  5. Kirish o'sganda o'sish
  6. O(1) doimiy, O(n^2) kvadratik (halokat)
  7. Deterministik (vaqt o'zgaruvchan)
  8. Real vaqt o'lchash (perf_counter)
  9. Bir marta shovqinli (barqaror uchun)
  10. Muhim (issiq yo'l, latency)
  11. Ko'p ishlaydigan kod (hot path)
  12. Bir marta, kichik ma'lumot, taxmin

Vazifa 2: Xatolarni tuzating

python
1.  # "sekin bo'lsa kerak" (taxmin)

2.  timeit(f, number=1)

3.  for x in a: for y in a  # O(n^2)

4.  # 100 element (prod million)

5.  # mikro-optimizatsiya (o'lchamasdan)
Javoblar
python
1.  o'lcha → eng katta ta'sir

2.  timeit(f, number=1000)

3.  set/dict (O(1) qidiruv)

4.  real hajm (katta data)

5.  o'lcha → eng katta ta'sir

Vazifa 3: Big-O

Sanang:

  1. O(1)
  2. O(n)
  3. O(n^2)
  4. Farq

Vazifa 4: Algoritm

Taqqoslang:

  1. O(n*m)
  2. O(n+m)
  3. Amal
  4. Struktura

Vazifa 5: Latency/throughput

Modellang:

  1. Latency
  2. Throughput
  3. Parallel
  4. Farq

Vazifa 6: O'lchash sikli

Modellang:

  1. O'lcha
  2. Eng og'ir
  3. Optimallashtir
  4. Qayta

Vazifa 7: O'ylash

Unumdorlik o'lchashda "avval o'lcha, keyin optimallashtir" va "taxmin adashtiradi" — takrorlanuvchi mavzular (28.4, 29.1). Nima uchun dasturchilarning unumdorlik haqidagi intuitsiyasi shunchalik tez-tez noto'g'ri chiqadi, va nega Big-O (nazariy o'sish) va haqiqiy o'lchash (amaliy) ikkalasi ham kerak — biri nazariya, biri amaliyot qanday to'ldiradi?

Javob

Qisqa javob: Dasturchilarning unumdorlik intuitsiyasi tez-tez noto'g'ri, chunki: (1) zamonaviy tizimlar murakkab (ko'p qatlam — kod, kutubxona, kesh, baza, tarmoq, OS, apparat) — qaysi qatlam sekin ekanini taxmin qilish qiyin (ko'rinmas); (2) intuitsiya kod hajmiga asoslanadi (ko'p qatorli kod "sekin" tuyuladi), lekin haqiqiy sekinlik kutishda (I/O — baza, tarmoq, disk — kod hajmiga bog'liq emas: bir qatorli baza so'rovi ming qatorli hisoblashdan sekinroq); (3) noto'g'ri intuitsiyalar (dasturchi "aqlli" mikro-optimizatsiyalarga e'tibor beradi — sikl, o'zgaruvchi — lekin ular kichik ta'sir; katta ta'sir arxitekturada — N+1 so'rov, O(n^2)); (4) kesh, JIT, kompilyator natijani o'zgartiradi (kutilmagan). Shuning uchun o'lchash zarur (intuitsiyani tekshirish). Big-O (nazariy) va haqiqiy o'lchash (amaliy) ikkalasi kerak, chunki ular turli savollarga javob beradi: Big-O — "qanday miqyoslanadi" (n o'sganda — kelajak, katta yuk; nazariy — mashinaga bog'liq emas, umumiy); u miqyos muammolarini oldindan ko'rsatadi (O(n^2) — million'da halokat, hozir 100'da tez ko'rinsa ham). Lekin Big-O doimiy koeffitsiyentlarni yashiradi (O(n) lekin har amal sekin bo'lsa — real sekin; O(n^2) lekin kichik n'da tez); u "kichik n'da qaysi tez" ni aytmaydi. Haqiqiy o'lchash — "hozir qanday" (real vaqt, real ma'lumot, real mashina — aniq, lekin bu sharoitga xos, umumlashmaydi). Birga: Big-O kelajakni (miqyos), o'lchash hozirni (aniq) beradi. Faqat Big-O — "nazariyada tez, amalda sekin" (doimiy koeffitsiyent); faqat o'lchash — "hozir tez, katta yukda halokat" (miqyosni ko'rmaydi). Muhandislik saboqlari: intuitsiya noto'g'ri (murakkab tizim, kutish yashirin) — o'lcha; Big-O — miqyos (kelajak), o'lchash — aniqlik (hozir); nazariya va amaliyot to'ldiradi (biri umumiy, biri aniq); ikkalasi bilan to'liq tushuncha.

1. Nega intuitsiya noto'g'ri

  • Murakkab tizim (ko'p qatlam — sekinlik ko'rinmas)
  • Intuitsiya kod hajmiga (sekinlik kutishda — I/O)
  • Mikro-optimizatsiyaga e'tibor (katta ta'sir arxitekturada)
  • Kesh, JIT (kutilmagan)

2. Big-O vs o'lchash (turli savol)

Vosita Savol
Big-O Qanday miqyoslanadi (kelajak)
O'lchash Hozir qanday (aniq)

3. Big-O cheklovi

Doimiy koeffitsiyentlarni yashiradi (O(n) lekin har amal sekin). "Kichik n'da qaysi" aytmaydi.

4. O'lchash cheklovi

Bu sharoitga xos (mashina, ma'lumot). Umumlashmaydi (miqyosni ko'rmaydi).

5. Muhandislik saboqlari

  1. Intuitsiya noto'g'ri (murakkab, kutish yashirin)
  2. Big-O — miqyos, o'lchash — aniqlik
  3. Nazariya + amaliyot to'ldiradi
  4. Ikkalasi — to'liq tushuncha

6. Xulosa

  1. Intuitsiya adashtiradi (murakkab tizim)
  2. Big-O — kelajak (miqyos), o'lchash — hozir (aniq)
  3. Faqat biri yetmaydi (koeffitsiyent yoki miqyos)
  4. Ikkalasi bilan to'liq

Nimani mustahkamlaydi: 2.1, 2.3-bo'limlar.


Xulosa

Bu darsda unumdorlikni o'lchashni o'rgandik.

Eng muhim uch fikr:

  1. Nega o'lchash va latency/throughput. Unumdorlik intuitsiyaga ishonib bo'lmaydi (taxmin ko'pincha noto'g'ri — haqiqiy muammo boshqa joyda) — o'lchash raqamlar beradi ("o'lchamasang — yaxshilay olmaysan"). Latency (kechikish) — bir amal qancha vaqt (javob vaqti — foydalanuvchi kutadi); Throughput (o'tkazuvchanlik) — vaqt birligida qancha ish (soniyada so'rov — sig'im). Ular farqli (ba'zan qarama-qarshi): tez javob (past latency) vs ko'p ish (yuqori throughput). Foydalanuvchi latencyni, tizim throughputni.

  2. Big-O va amal sanash. Big-O — ishlash vaqti kirish (n) o'sganda qanday o'sishi: O(1) (doimiy — eng yaxshi), O(log n), O(n) (chiziqli), O(n log n), O(n^2) (kvadratik — tez o'sadi, yomon), O(2^n) (halokat); kichik n'da farq ko'rinmaydi, katta n'da halokat (miqyos). Amal sanash — deterministik o'lchash (vaqt o'zgaruvchan — mashina, yuk; amal soni barqaror — bir kirish → bir son); for x in data = O(n), ichma-ich = O(n^2); Big-O ni amalda ko'rsatadi. Timing (perf_counter) va benchmark (timeit — ko'p marta, barqaror) — real vaqt (lekin shovqinli).

  3. Nima o'lchash va optimizatsiya asosi. Nima o'lchash — muhimni (foydalanuvchi his qiladigan — latency; eng ko'p ishlaydigan — issiq yo'l; miqyoslanuvchi — Big-O; resurs cheklovi), hamma narsani emas (shovqin — 28.10 RED/USE). Tuzoqlar: bir marta o'lchash (shovqinli), noto'g'ri sharoit (kichik ma'lumot), Big-O e'tiborsizlik, mikro-optimizatsiya. O'lchash — optimizatsiyaning asosi: "o'lcha → tahlil → optimallashtir → qayta o'lcha" (28.4 — avval o'lcha; kesh 29.3, navbat 29.4, miqyos 29.6 asosi). Big-O (nazariy — miqyos, kelajak) va o'lchash (amaliy — aniq, hozir) ikkalasi kerak (biri umumiy, biri aniq — to'ldiradi). "O'lchamasang — yaxshilay olmaysan".

Keyingi darsda profiling amaliyotini o'rganamiz: kodning qaysi qismi sekin ekanini aniqlash — cProfile, line_profiler, xotira profileri va issiq nuqtalarni (bottleneck) topish.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!