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

29.9-dars: Xotira optimizatsiyasi

29-QISM — MIQYOS VA UNUMDORLIK · 9-dars


1. Kirish va motivatsiya

Unumdorlik faqat tezlik emas — xotira ham muhim resurs. Xotira tugasa, dastur yiqiladi (out of memory) yoki sekinlashadi (svop — diskka ko'chirish). Katta ma'lumot bilan ishlaganda (million qator, katta fayl) butun ma'lumotni xotiraga yuklash — halokat (10 GB fayl 8 GB xotiraga sig'maydi). Yoki dastur asta-sekin xotira yeydi (memory leak) — soatlar davomida yiqiladi. Xotira optimizatsiyasi — dastur xotira sarfini kamaytirish: ma'lumotni oqim (stream) sifatida qayta ishlash (generatorlar), obyektlarni ixcham qilish (__slots__), to'g'ri ma'lumot tuzilmalari, xotira oqishlarini oldini olish. Xotira — tezlik kabi optimallashtiriladigan resurs.

Xotira optimizatsiyasi — dastur xotira sarfini kamaytirish usullari: xotira o'lchash (sys.getsizeof, tracemalloc — 29.2), generatorlar (13-qism — oqim, butun ma'lumotni yuklamaslik), __slots__ (obyekt xotirasini kamaytirish), ma'lumot tuzilmalari (to'g'ri tanlash — list vs set vs array), xotira oqishi (memory leak — keraksiz havolalar), time-space tradeoff (29.3 — vaqt vs xotira). Prinsip: katta ma'lumot — oqim, xotira o'lchash, ixcham obyekt. Bu profiling (29.2 — xotira profiling), kesh (29.3 — xotira narxi) bilan bog'liq. Xotira optimizatsiyasi — xotira-samarali kod. Kam xotira — barqaror tizim.

Real vaziyat. Bir dastur 5 GB CSV faylni qayta ishlardi — butun faylni ro'yxatga yuklardi (list(reader)) — xotira tugab yiqilardi (out of memory). Xotira optimizatsiyasi: fayl generator bilan qator-qator o'qildi (for row in reader — butun yuklamasdan), obyektlar __slots__ bilan ixcham qilindi. Endi dastur 5 GB faylni 100 MB xotirada qayta ishladi (oqim — bir vaqtda bir qator). Xotira optimizatsiyasi — katta ma'lumotni kichik xotirada.

Bu darsda xotira optimizatsiyasini o'rganamiz.

Bu darsda:

  • Nega xotira muhim
  • Generatorlar (oqim)
  • Xotira o'lchash
  • __slots__ (ixcham obyekt)
  • Ma'lumot tuzilmalari
  • Xotira oqishi (memory leak)
  • Xotira optimizatsiyasi amaliyoti
  • Amaliy: xotira modeli

ℹ Misollar sof Python (sys.getsizeof, generatorlar) bilan xotira mantiqini ko'rsatadi (deterministik).


2. Nazariya — chuqur tushuntirish

2.1. Nega xotira muhim

Cheklangan resurs:

Xotira cheklangan (masalan 8 GB):
   tugasa → dastur yiqiladi (out of memory)
   yoki svop (diskka — sekin)

katta ma'lumot: butun yuklash → halokat
   10 GB fayl → 8 GB xotira (sig'maydi!)

Nega xotira — xotira cheklangan resurs (server 8 GB, 16 GB): tugasa dastur yiqiladi (out of memory — OOM) yoki sekinlashadi (svop — diskka ko'chirish, sekin). Sabab: katta ma'lumot (million qator, katta fayl) butun xotiraga sig'maydi (10 GB fayl — 8 GB xotira); yoki dastur asta xotira yeydi (leak — soatlar davomida yiqiladi). Xotira — tezlik kabi optimallashtiriladigan resurs (nafaqat CPU). Xotira-samarali kod — katta ma'lumot bilan ishlaydi (kichik xotirada), barqaror (yiqilmaydi). Xotira — cheklangan, muhim resurs. Kam xotira — barqaror.

2.2. Generatorlar (oqim)

Butun ma'lumotni yuklamaslik:

python
# YOMON: butun faylni xotiraga (katta — halokat)
qatorlar = list(open("katta.csv"))   # 10 GB xotirada

# YAXSHI: generator — qator-qator (oqim)
for qator in open("katta.csv"):      # bir vaqtda bir qator
    qayta_ishla(qator)               # kichik xotira

Generatorlar (13-qism) — ma'lumotni oqim (stream) sifatida, butun yuklamasdan qayta ishlash: list(...) (butun ma'lumot xotirada — katta) o'rniga generator (for x in ..., yield — bir vaqtda bir element). Sabab: katta ma'lumot (million qator, katta fayl) butun yuklash — halokat (xotira tugaydi); generator har elementni kerak bo'lganda beradi (oqim — bir vaqtda bitta, xotira kichik). Masalan 10 GB fayl generator bilan 10 MB xotirada (bir qator). Bu xotira optimizatsiyasining eng kuchli usuli (katta ma'lumot uchun). Generator — oqim (butun emas). Bir vaqtda bir element — kichik xotira.

2.3. Xotira o'lchash

Nima qancha xotira:

python
import sys
sys.getsizeof([1, 2, 3])       # obyekt hajmi (bayt)
sys.getsizeof("salom")

# tracemalloc 29.2-bob — qayerda ko'p xotira
import tracemalloc
tracemalloc.start()
# ... kod ...
joriy, eng_yuqori = tracemalloc.get_traced_memory()

Xotira o'lchash — optimizatsiyani o'lchashdan boshlash (29.1 kabi — nima og'ir?): sys.getsizeof(obyekt) (obyekt xotirasi — bayt), tracemalloc (29.2 — dastur xotira sarfi, eng ko'p olgan joylar), memory_profiler (qator bo'yicha). Sabab: xotira muammosini tuzatish uchun qayerda ko'p (taxmin emas — 29.1); o'lchamasdan optimizatsiya — ko'r. Odatiy og'ir joylar: katta ro'yxatlar, ko'p obyekt, keraksiz nusxalar, kesh 29.3-bob. Avval o'lcha, keyin optimallashtir 29.1-bob. Xotira o'lchash — muammo manzilini topish. O'lchash — optimizatsiya asosi.

2.4. __slots__ (ixcham obyekt)

Obyekt xotirasini kamaytirish:

python
# ODATIY obyekt — __dict__ (moslashuvchan, lekin katta)
class Nuqta:
    def __init__(self, x, y): self.x = x; self.y = y

# __slots__ — belgilangan maydonlar (ixcham, kam xotira)
class Nuqta:
    __slots__ = ("x", "y")   # __dict__ yo'q — kam xotira
    def __init__(self, x, y): self.x = x; self.y = y

__slots__ — obyekt xotirasini kamaytirish: odatiy Python obyekti har birida __dict__ (lug'at — moslashuvchan, istalgan atribut, lekin katta — har obyekt lug'at); __slots__ maydonlarni oldindan belgilaydi (__slots__ = ("x", "y")) — __dict__ yaratilmaydi (ixcham, kam xotira). Sabab: ko'p obyekt (million nuqta, foydalanuvchi) — har birida __dict__ katta (jami ko'p xotira); __slots__ buni keskin kamaytiradi (2-3 barobar). Ehtiyot: __slots__ moslashuvchanlikni kamaytiradi (yangi atribut qo'shib bo'lmaydi) — faqat ko'p, sodda obyektga. __slots__ — ixcham obyekt (ko'p obyektga). Belgilangan maydon — kam xotira.

2.5. Ma'lumot tuzilmalari

To'g'ri tuzilma tanlash:

Tuzilma Xotira/tezlik
list Moslashuvchan, o'rta xotira
set/dict Tez qidiruv (O(1)), ko'proq xotira
tuple O'zgarmas, kam xotira (list'dan)
array Raqamlar — ixcham (list'dan kam)
generator Oqim — eng kam (yuklamaydi)

Ma'lumot tuzilmalari — to'g'ri tuzilma xotira va tezlikni belgilaydi: list (moslashuvchan, o'rta xotira), set/dict (tez qidiruv O(1), lekin ko'proq xotira — hash), tuple (o'zgarmas — list'dan kam xotira), array (bir xil turdagi raqamlar — list'dan ancha kam, ixcham), generator (oqim — eng kam, yuklamaydi — 29.9.2), bytes (matn/ikkilik — ixcham). Sabab: har tuzilma xotira/tezlik savdosi (29.3 — time-space) — to'g'ri tanlov muhim (million raqam list vs array — katta farq). Ish turiga qarab (qidiruv — set, raqamlar — array, oqim — generator). Tuzilma — xotira va tezlik. To'g'ri tuzilma — samarali.

2.6. Xotira oqishi (memory leak)

Keraksiz havolalar:

python
# xotira oqishi — obyektlar o'chmaydi (havola qoladi)
kesh = {}
def qayta_ishla(data):
    kesh[data.id] = data   # kesh o'smoqda (hech o'chmaydi!)
    # → xotira asta to'ladi (leak)

# yechim: cheklangan kesh (LRU — 29.3), havolani tozalash

Xotira oqishi (memory leak) — obyektlar o'chmasligi (havola qoladi — Python garbage collector o'chirolmaydi): masalan cheksiz o'suvchi kesh (kesh[id] = data — hech o'chmaydi), global ro'yxatga qo'shib borish, aylanma havolalar (circular reference). Natija: xotira asta to'ladi (soatlar/kunlar davomida — uzoq ishlayotgan server), oxirda yiqiladi (OOM). Sabab: Python obyektni havola bo'lsa o'chirmaydi (garbage collection — havola yo'q bo'lganda); keraksiz havola — leak. Yechim: cheklangan kesh (LRU — 29.3), havolani tozalash (del, weakref), profiling (29.2 — xotira o'sishi). Memory leak — asta xotira to'lishi. Keraksiz havola — leak.

2.7. Xotira optimizatsiyasi amaliyoti

Xotira optimizatsiyasi amaliyotlari: o'lcha avval (29.1 — sys.getsizeof, tracemalloc — qayerda ko'p); generator (katta ma'lumot — oqim, butun yuklamas); __slots__ (ko'p obyekt — ixcham); to'g'ri tuzilma (raqamlar — array, qidiruv — set); kesh cheklovi (LRU — 29.3, cheksiz emas); havolani tozalash (leak oldini — del, weakref); lazy loading (kerak bo'lganda yuklash); xotira monitoring (28.10 — prodda xotira, leak). Tuzoqlar: butun yuklash (katta ma'lumot — generator), cheksiz kesh (leak), __slots__siz ko'p obyekt. Yaxshi xotira optimizatsiyasi — o'lchash, generator, ixcham. Amaliyot — xotira-samarali kod. O'lcha, oqim, ixcham.

2.8. Xotira — vaqt bilan muvozanat

Xotira optimizatsiyasi asosiy g'oyasi — xotira va vaqt muvozanati (time-space tradeoff — 29.3): ba'zan vaqtni tejash uchun xotira ishlatiladi (kesh — 29.3, oldindan hisoblash), ba'zan xotirani tejash uchun vaqt (generator — qayta o'qish, siqish). To'g'ri muvozanat kontekstga bog'liq (xotira cheklangan bo'lsa — generator; tezlik muhim bo'lsa — kesh). Bu unumdorlik (29.1 — o'lchash), profiling (29.2 — xotira), kesh (29.3 — xotira narxi) bilan bir tizim. "Xotira ham tezlik kabi resurs" (optimallashtiriladigan). Katta ma'lumot davrida (big data, ML) xotira optimizatsiyasi kritik. Xotira optimizatsiyasi — resursni muvozanatlash. Vaqt vs xotira — kontekstga qarab.


3. Tez ma'lumotnoma

python
import sys

# XOTIRA O'LCHASH:
sys.getsizeof(obyekt)   # obyekt hajmi (bayt)
import tracemalloc; tracemalloc.start()   # dastur xotirasi

# GENERATOR (oqim — butun yuklamaydi):
def oqi(fayl):
    for qator in open(fayl):   # bir vaqtda bir qator
        yield qayta_ishla(qator)
# list(...) — butun xotirada (katta) · generator — oqim (kichik)

# __SLOTS__ (ixcham obyekt — ko'p obyektga):
class Nuqta:
    __slots__ = ("x", "y")   # __dict__ yo'q (kam xotira)

# TUZILMALAR (xotira/tezlik):
# list (moslashuvchan) · tuple (kam) · array (raqamlar ixcham)
# set/dict (tez qidiruv, ko'p xotira) · generator (oqim, eng kam)

# MEMORY LEAK: cheksiz kesh, global ro'yxat → asta to'ladi
# yechim: LRU kesh, del, weakref

# PRINSIP: o'lcha → generator (katta) → __slots__ (ko'p obyekt)

Xotira optimizatsiyasi xulosasi

Xotira — cheklangan resurs (tugasa yiqiladi — OOM)
Generator (oqim — butun yuklamaydi, katta ma'lumot uchun)
__slots__ (ixcham obyekt — ko'p obyektga) · to'g'ri tuzilma
Memory leak (cheksiz kesh, havola — asta to'ladi)
O'lcha (getsizeof, tracemalloc) · vaqt-xotira muvozanati

4. Batafsil misollar

Misollar sof Python (sys.getsizeof, generatorlar) bilan xotira mantiqini ko'rsatadi.

Misol 1 — Generator vs ro'yxat (xotira)

python
"""Generator: oqim (bir element) vs ro'yxat (butun) — xotira farqi."""
import sys


def royxat_usul(n: int) -> list:
    # butun ro'yxat xotirada
    return [x * x for x in range(n)]


def generator_usul(n: int):
    # generator — bir vaqtda bir element (yield)
    return (x * x for x in range(n))


def main() -> None:
    n = 1000

    print("=== 1. Ro'yxat (butun xotirada) ===")
    royxat = royxat_usul(n)
    print(f"  hajm: {sys.getsizeof(royxat)} bayt ({n} element)")

    print("\n=== 2. Generator (oqim) ===")
    gen = generator_usul(n)
    print(f"  hajm: {sys.getsizeof(gen)} bayt (bir vaqtda bir element)")

    print("\n=== 3. Farq ===")
    royxat_hajm = sys.getsizeof(royxat)
    gen_hajm = sys.getsizeof(gen)
    print(f"  ro'yxat: {royxat_hajm}, generator: {gen_hajm}")
    print(f"  generator ~{royxat_hajm // gen_hajm}x kichik")

    print("\n=== 4. Katta ma'lumot ===")
    print("  million element: ro'yxat — MB, generator — baytlar")
    print("  generator butun yuklamaydi (oqim)")
    print("  ⭐ Generator — oqim (kichik xotira)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Ro'yxat (butun xotirada) ===
  hajm: 8856 bayt (1000 element)

=== 2. Generator (oqim) ===
  hajm: 208 bayt (bir vaqtda bir element)

=== 3. Farq ===
  ro'yxat: 8856, generator: 208
  generator ~42x kichik

=== 4. Katta ma'lumot ===
  million element: ro'yxat — MB, generator — baytlar
  generator butun yuklamaydi (oqim)
  ⭐ Generator — oqim (kichik xotira)

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

Misol 2 — slots (ixcham obyekt)

python
"""__slots__: obyekt xotirasini kamaytirish (__dict__ o'rniga)."""
import sys


class OddiyNuqta:
    # __dict__ bilan (moslashuvchan, katta)
    def __init__(self, x: int, y: int) -> None:
        self.x = x
        self.y = y


class SlotsNuqta:
    # __slots__ (ixcham, __dict__ yo'q)
    __slots__ = ("x", "y")

    def __init__(self, x: int, y: int) -> None:
        self.x = x
        self.y = y


def main() -> None:
    oddiy = OddiyNuqta(1, 2)
    slots = SlotsNuqta(1, 2)

    print("=== 1. Oddiy obyekt (__dict__) ===")
    print(f"  __dict__ bor: {hasattr(oddiy, '__dict__')}")
    print(f"  __dict__ hajmi: {sys.getsizeof(oddiy.__dict__)} bayt")

    print("\n=== 2. __slots__ obyekt ===")
    print(f"  __dict__ bor: {hasattr(slots, '__dict__')}")
    print("  __dict__ yo'q (ixcham)")

    print("\n=== 3. Ko'p obyekt ta'siri ===")
    print("  million nuqta: oddiy — har birida __dict__ (katta)")
    print("  __slots__ — belgilangan maydon (2-3x kam)")

    print("\n=== 4. Ehtiyot ===")
    print("  __slots__ — yangi atribut qo'shib bo'lmaydi")
    print("  faqat ko'p, sodda obyektga")
    print("  ⭐ __slots__ — ixcham obyekt (ko'p obyektga)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Oddiy obyekt (__dict__) ===
  __dict__ bor: True
  __dict__ hajmi: 296 bayt

=== 2. __slots__ obyekt ===
  __dict__ bor: False
  __dict__ yo'q (ixcham)

=== 3. Ko'p obyekt ta'siri ===
  million nuqta: oddiy — har birida __dict__ (katta)
  __slots__ — belgilangan maydon (2-3x kam)

=== 4. Ehtiyot ===
  __slots__ — yangi atribut qo'shib bo'lmaydi
  faqat ko'p, sodda obyektga
  ⭐ __slots__ — ixcham obyekt (ko'p obyektga)

Nima ko'rsatdi: 2.4-bo'lim.

Misol 3 — Ma'lumot tuzilmalari (xotira)

python
"""Tuzilmalar: turli tuzilma xotirasi (to'g'ri tanlov muhim)."""
import sys
from array import array


def main() -> None:
    raqamlar = list(range(100))

    print("=== 1. list (moslashuvchan) ===")
    list_hajm = sys.getsizeof(raqamlar)
    print(f"  hajm: {list_hajm} bayt")

    print("\n=== 2. tuple (o'zgarmas — kam) ===")
    tuple_hajm = sys.getsizeof(tuple(raqamlar))
    print(f"  hajm: {tuple_hajm} bayt")

    print("\n=== 3. array (raqamlar — ixcham) ===")
    arr = array("i", raqamlar)   # butun sonlar
    array_hajm = sys.getsizeof(arr)
    print(f"  hajm: {array_hajm} bayt")

    print("\n=== 4. Taqqoslash ===")
    print(f"  list: {list_hajm}, tuple: {tuple_hajm}, array: {array_hajm}")
    print(f"  tuple < list (o'zgarmas)")
    print("  array — raqamlar uchun ixcham (list'dan kam)")
    print("  ma'lumot turiga qarab tuzilma")
    print("  ⭐ To'g'ri tuzilma — kam xotira")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. list (moslashuvchan) ===
  hajm: 856 bayt

=== 2. tuple (o'zgarmas — kam) ===
  hajm: 848 bayt

=== 3. array (raqamlar — ixcham) ===
  hajm: 480 bayt

=== 4. Taqqoslash ===
  list: 856, tuple: 848, array: 480
  tuple < list (o'zgarmas)
  array — raqamlar uchun ixcham (list'dan kam)
  ma'lumot turiga qarab tuzilma
  ⭐ To'g'ri tuzilma — kam xotira

Nima ko'rsatdi: 2.5-bo'lim.

Misol 4 — Xotira oqishi (memory leak)

python
"""Memory leak: cheksiz kesh asta xotira yeydi (cheklash bilan yechim)."""
from collections import OrderedDict


class LeakliKesh:
    """Cheksiz kesh — memory leak (hech o'chmaydi)."""

    def __init__(self) -> None:
        self.kesh: dict = {}

    def qosh(self, kalit: int, data: str) -> None:
        self.kesh[kalit] = data   # cheksiz o'sadi (leak!)


class CheklanganKesh:
    """Cheklangan kesh (LRU) — xotira barqaror."""

    def __init__(self, sigim: int) -> None:
        self.sigim = sigim
        self.kesh: OrderedDict = OrderedDict()

    def qosh(self, kalit: int, data: str) -> None:
        self.kesh[kalit] = data
        if len(self.kesh) > self.sigim:
            self.kesh.popitem(last=False)   # eng eski o'chadi


def main() -> None:
    print("=== 1. Leakli kesh (cheksiz o'sadi) ===")
    leak = LeakliKesh()
    for i in range(1000):
        leak.qosh(i, f"data-{i}")
    print(f"  1000 qo'shildi → kesh hajmi: {len(leak.kesh)} (hammasi!)")

    print("\n=== 2. Cheklangan kesh (LRU) ===")
    cheklangan = CheklanganKesh(sigim=100)
    for i in range(1000):
        cheklangan.qosh(i, f"data-{i}")
    print(f"  1000 qo'shildi → kesh hajmi: {len(cheklangan.kesh)} (chegarada)")

    print("\n=== 3. Farq ===")
    print(f"  leakli: {len(leak.kesh)} (asta to'ladi — OOM)")
    print(f"  cheklangan: {len(cheklangan.kesh)} (barqaror)")

    print("\n=== 4. Memory leak sababi ===")
    print("  havola qoladi → o'chmaydi (garbage collector)")
    print("  yechim: cheklangan kesh (LRU), del, weakref")
    print("  ⭐ Memory leak — cheksiz o'sish (cheklash yechim)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Leakli kesh (cheksiz o'sadi) ===
  1000 qo'shildi → kesh hajmi: 1000 (hammasi!)

=== 2. Cheklangan kesh (LRU) ===
  1000 qo'shildi → kesh hajmi: 100 (chegarada)

=== 3. Farq ===
  leakli: 1000 (asta to'ladi — OOM)
  cheklangan: 100 (barqaror)

=== 4. Memory leak sababi ===
  havola qoladi → o'chmaydi (garbage collector)
  yechim: cheklangan kesh (LRU), del, weakref
  ⭐ Memory leak — cheksiz o'sish (cheklash yechim)

Nima ko'rsatdi: 2.6-bo'lim.


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

Noto'g'ri fikr To'g'risi
"Faqat tezlik muhim" Xotira ham (cheklangan)
"Butun ma'lumotni yukla" Generator (oqim — katta uchun)
"Obyekt xotirasi bir xil" __slots__ (ixcham)
"Har tuzilma bir xil" To'g'ri tanlov (array, set)
"Kesh cheksiz" Cheklangan (LRU — leak)
"Python leak yo'q" Havola — leak
"Xotira o'lchamasdan" O'lcha (getsizeof, tracemalloc)
"__slots__ har obyektga" Ko'p, sodda obyektga

6. Keng tarqalgan xatolar va yechimlari

1. Butun ma'lumotni yuklash

python
qatorlar = list(open("katta.csv"))   # OOM               # ⚠️
for qator in open("katta.csv"): ...   # generator         # ✅

2. Cheksiz kesh (leak)

python
kesh[id] = data   # hech o'chmaydi (asta to'ladi)        # ⚠️
# LRU kesh (cheklangan — 29.3)                            # ✅

3. Ko'p obyekt __slots__siz

python
# million obyekt, har birida __dict__ (katta)            # ⚠️
class X: __slots__ = (...)   # ixcham                      # ✅

4. Noto'g'ri tuzilma (raqamlar)

python
raqamlar = [1, 2, ...]   # list (katta — million raqam)  # ⚠️
array("i", raqamlar)   # ixcham                            # ✅

5. Xotira o'lchamasdan optimizatsiya

python
# "bu ko'p xotira yeydi" (taxmin)                         # ⚠️
tracemalloc / getsizeof   # o'lcha 29.1-bob                  # ✅

6. Keraksiz nusxalar

python
yangi = data[:]   # har safar nusxa (xotira)             # ⚠️
# o'rniga havola yoki generator (nusxasiz)                # ✅

7. Global o'suvchi ro'yxat

python
JURNAL = []   # har so'rov qo'shadi (cheksiz — leak)      # ⚠️
# cheklangan (deque maxlen) yoki tashqi log               # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 13-qism (o'tilgan): Generatorlar, iteratorlar
  • 29.2-dars (o'tilgan): Profiling — xotira profiling
  • 29.3-dars (o'tilgan): Kesh — xotira narxi (time-space)
  • 24-qism (o'tilgan): Ma'lumot tahlili — katta ma'lumot
  • 28.10-dars (o'tilgan): Monitoring — xotira, leak

8. Eng yaxshi amaliyotlar

  1. O'lcha avval (getsizeof, tracemalloc).

  2. Generator (katta ma'lumot — oqim).

  3. __slots__ (ko'p obyekt — ixcham).

  4. To'g'ri tuzilma (array, set — ish turiga).

  5. Kesh cheklovi (LRU — leak oldini).

  6. Havolani tozalash (del, weakref).

  7. Lazy loading (kerak bo'lganda).

  8. Xotira monitoring (prodda — leak).


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # nega xotira muhim?
2.  # OOM nima?
3.  # generator nima (xotira)?
4.  # list vs generator?
5.  # getsizeof nima?
6.  # __slots__ nima?
7.  # __slots__ nega kam xotira?
8.  # array vs list?
9.  # memory leak nima?
10. # leak sababi?
11. # leak yechimi?
12. # time-space tradeoff?
Javoblar
  1. Cheklangan resurs (tugasa yiqiladi)
  2. Out of memory (xotira tugadi)
  3. Oqim — bir vaqtda bir element (butun emas)
  4. list butun xotirada, generator oqim
  5. Obyekt xotirasi (bayt)
  6. Obyekt maydonlarini belgilash (ixcham)
  7. dict yaratmaydi (har obyekt lug'at)
  8. array raqamlar uchun ixcham (list'dan kam)
  9. Obyektlar o'chmaydi (havola qoladi)
  10. Cheksiz kesh, global ro'yxat, havola
  11. Cheklangan kesh (LRU), del, weakref
  12. Vaqt vs xotira muvozanati

Vazifa 2: Xatolarni tuzating

python
1.  qatorlar = list(open("katta.csv"))

2.  kesh[id] = data   # cheksiz

3.  # million obyekt __slots__siz

4.  raqamlar = [1, 2, ...]   # million

5.  # "ko'p xotira" (taxmin)
Javoblar
python
1.  for qator in open(...)  # generator

2.  LRU kesh (cheklangan)

3.  __slots__ (ixcham)

4.  array("i", raqamlar)

5.  tracemalloc yoki getsizeof bilan

Vazifa 3: Generator

Modellang:

  1. Ro'yxat
  2. Generator
  3. Xotira
  4. Farq

Vazifa 4: slots

Modellang:

  1. Oddiy
  2. slots
  3. dict
  4. Xotira

Vazifa 5: Tuzilmalar

Modellang:

  1. list
  2. tuple
  3. array
  4. Taqqoslash

Vazifa 6: Memory leak

Modellang:

  1. Leakli kesh
  2. Cheklangan
  3. O'sish
  4. Yechim

Vazifa 7: O'ylash

Xotira optimizatsiyasida generatorlar (oqim) kuchli vosita — 10 GB faylni 10 MB xotirada qayta ishlash mumkin. Nima uchun "butun ma'lumotni yuklash o'rniga oqim (bir vaqtda bir element)" katta ma'lumot davrida (big data) shunchalik muhim tamoyil, va nega "xotira va vaqt muvozanati" (time-space tradeoff) optimizatsiyaning tub xususiyati — biror narsani tejash uchun boshqasini sarflash nega muqarrar?

Javob

Qisqa javob: "Oqim (bir vaqtda bir element)" katta ma'lumot davrida muhim, chunki: ma'lumot hajmi xotiradan katta bo'lishi mumkin (10 GB fayl, 8 GB xotira; yoki cheksiz oqim — real vaqt hodisalari) — butun yuklash imkonsiz (sig'maydi). Oqim (generator) ma'lumotni qism-qism qayta ishlaydi (bir vaqtda bir element) — xotira hajmga bog'liq emas (doimiy, kichik — bir element); 10 GB ham, 10 TB ham bir xil kichik xotira (har element o'tadi, ketadi). Bu miqyoslanuvchanlik: butun yuklash — xotira ma'lumot hajmiga proporsional (O(n) xotira — miqyoslanmaydi); oqim — doimiy xotira (O(1) — miqyoslanadi, cheksiz ma'lumot). Big data (katta ma'lumot) da ma'lumot doim xotiradan katta — oqim majburiy. "Xotira va vaqt muvozanati" (time-space tradeoff) optimizatsiyaning tub xususiyati, chunki: ular almashtiriladigan resurslar — biror hisoblash natijasini saqlash (xotira) qayta hisoblashni (vaqt) tejaydi (kesh — 29.3); yoki saqlamaslik (xotira tejash) qayta hisoblashni (vaqt) talab qiladi (generator — qayta o'qish). Ikkalasini birga tejab bo'lmaydi (odatda) — chunki natijani ishlatish uchun u biror joyda bo'lishi kerak (xotirada — tez, lekin joy; yoki qayta hisoblanadi — joy yo'q, lekin vaqt). Bu fizik cheklov (ma'lumot yo saqlanadi — joy, yo hisoblanadi — vaqt; uchinchi yo'l yo'q). Shuning uchun optimizatsiya — savdo (bir resursni boshqasiga almashtirish, kontekstga qarab): xotira cheklangan bo'lsa — vaqt sarfla (generator, siqish); vaqt muhim bo'lsa — xotira sarfla (kesh, oldindan hisoblash). "Bepul tushlik yo'q" (no free lunch) — har yaxshilanish narx bilan. Muhandislik saboqlari: oqim — doimiy xotira (miqyoslanadi, katta ma'lumot); butun yuklash — proporsional xotira (miqyoslanmaydi); time-space — almashtiriladigan resurslar (biror narsani tejash — boshqasini sarflash); optimizatsiya — savdo (kontekstga qarab tanlash), bepul yaxshilanish yo'q.

1. Nega oqim muhim (big data)

Ma'lumot hajmi xotiradan katta (10 GB fayl, cheksiz oqim). Butun yuklash imkonsiz. Oqim — qism-qism (xotira hajmga bog'liq emas).

2. Miqyoslanuvchanlik

Usul Xotira
Butun yuklash O(n) — hajmga proporsional (miqyoslanmaydi)
Oqim (generator) O(1) — doimiy (miqyoslanadi)

3. Nega time-space tradeoff tub

Xotira va vaqt — almashtiriladigan. Saqlash (xotira) → vaqt tejaydi (kesh). Saqlamaslik (xotira tejash) → vaqt sarflaydi (qayta hisoblash).

4. Nega muqarrar

Natija biror joyda bo'lishi kerak: xotirada (tez, joy) yoki hisoblanadi (joy yo'q, vaqt). Uchinchi yo'l yo'q (fizik cheklov).

5. Muhandislik saboqlari

  1. Oqim — doimiy xotira (miqyoslanadi)
  2. Butun yuklash — proporsional (miqyoslanmaydi)
  3. Time-space — almashtiriladigan resurslar
  4. Optimizatsiya — savdo (bepul tushlik yo'q)

6. Xulosa

  1. Oqim — hajmdan mustaqil xotira (big data)
  2. Butun yuklash — imkonsiz (katta ma'lumot)
  3. Time-space — resurslar almashtiriladigan (muqarrar savdo)
  4. Kontekstga qarab tanlash (xotira yoki vaqt)

Nimani mustahkamlaydi: 2.2, 2.8-bo'limlar.


Xulosa

Bu darsda xotira optimizatsiyasini o'rgandik.

Eng muhim uch fikr:

  1. Nega xotira va generatorlar. Xotira cheklangan resurs (tugasa dastur yiqiladi — OOM, yoki svop — sekin); katta ma'lumot butun yuklash — halokat (10 GB fayl, 8 GB xotira), yoki asta xotira yeydi (leak). Xotira — tezlik kabi optimallashtiriladigan resurs. Generatorlar (13-qism) — ma'lumotni oqim sifatida, butun yuklamasdan (list(...) o'rniga yield — bir vaqtda bir element); katta ma'lumot (million qator, 10 GB fayl) generator bilan kichik xotirada (bir element); eng kuchli usul (katta ma'lumot uchun).

  2. O'lchash, slots, tuzilmalar. Xotira o'lchash — sys.getsizeof(obyekt) (obyekt hajmi), tracemalloc (29.2 — dastur xotirasi, eng ko'p joylar); avval o'lcha 29.1-bob. __slots__ — obyekt xotirasini kamaytirish (odatiy obyekt __dict__ — katta; __slots__ = ("x", "y") — __dict__ yo'q, ixcham, 2-3x kam); faqat ko'p, sodda obyektga (moslashuvchanlikni kamaytiradi). Ma'lumot tuzilmalari: list (moslashuvchan), tuple (o'zgarmas — kam), array (raqamlar — ixcham), set/dict (tez qidiruv, ko'p xotira), generator (oqim — eng kam); ish turiga qarab tanlash.

  3. Memory leak va muvozanat. Xotira oqishi (memory leak) — obyektlar o'chmasligi (havola qoladi — cheksiz kesh, global ro'yxat, aylanma havola); xotira asta to'ladi (uzoq ishlayotgan server — OOM); yechim: cheklangan kesh (LRU — 29.3), havolani tozalash (del, weakref), profiling 29.2-bob. Xotira optimizatsiyasi — xotira va vaqt muvozanati (time-space tradeoff — 29.3): vaqt tejash uchun xotira (kesh) yoki xotira tejash uchun vaqt (generator — qayta o'qish); almashtiriladigan resurslar (biror narsani tejash — boshqasini sarflash, bepul tushlik yo'q). Oqim — doimiy xotira (miqyoslanadi, katta ma'lumot — O(1)); butun yuklash — proporsional (O(n) — miqyoslanmaydi). "Xotira ham tezlik kabi resurs" (big data, ML davrida kritik).

Keyingi darsda benchmark va yuk testini o'rganamiz: tizim unumdorligini sinash — benchmark (nazorat sinovi), yuk testi (load testing — ko'p foydalanuvchi simulyatsiyasi), stress testi va tizim chegaralarini topish.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
29.9-dars: Xotira optimizatsiyasi — IlmHamroh