5-qism · AI muhandisi uchun Python·25-bob
Performans, toza kod va keyingi qadamlar: AI/ML yo'l xaritasi
O'lchamasdan optimallashtirmang: timeit, cProfile, tracemalloc; algoritmik murakkablik va to'g'ri ma'lumot tuzilmasi; keshlash va vektorlashtirish; professional kod mezonlari; kurs bo'yicha o'z-o'zini tekshirish va ML/AI Engineering'ga yo'l xaritasi.
Oxirgi bob ikki qismdan iborat. Birinchisi — performans: kod sekin bo'lsa, qanday qilib sababini topish va tuzatish. Ikkinchisi — yo'l xaritasi: bu kursdan keyin ML Engineering va AI Engineering'ga qanday o'tish, nimani, qaysi tartibda o'rganish va o'zingizni qanday tekshirish.
Big-O murakkablik: kod ma'lumot o'sishi bilan qanday sekinlashadi — bobning 3-bo'limidagi g'oya PyCon ma'ruzasida.
1. Optimallashtirishning birinchi qoidasi#
"Premature optimization is the root of all evil." — Donald Knuth
Ko'p dasturchilar kodni "tezroq bo'lsin" deb murakkablashtiradi — va ko'pincha noto'g'ri joyni. Dastur vaqtining 90% i odatda kodning 10% ida o'tadi. O'sha 10% ni taxmin bilan topib bo'lmaydi — o'lchash kerak.
To'g'ri ishlashini ta'minlang
Testlar bilan (16-bob). Tez, lekin noto'g'ri kod — foydasiz.Yetarlicha tezmi?
Kun bir marta ishlaydigan 3 soniyalik skript — optimallashtirish shart emas.O'lchang
Profiler bilan qayerda vaqt ketayotganini toping.Eng katta muammoni tuzating
Odatda algoritm yoki ma'lumot tuzilmasi — "mikro-optimallashtirish" emas.Qayta o'lchang
Yaxshilanish haqiqatan bo'ldimi? Testlar hali o'tyaptimi?
2. O'lchash vositalari#
timeit — kichik kod bo'laklarini solishtirish#
import timeit
setup = "items = list(range(100_000)); s = set(items); q = list(range(0, 200_000, 20))"
timeit.timeit("sum(1 for x in q if x in items)", setup, number=1) # ~2.16 s
timeit.timeit("sum(1 for x in q if x in s)", setup, number=1) # ~0.0005 sJupyter'da: %timeit expr (22-bob). timeit kodni ko'p marta ishlatib,
tasodifiy shovqinni kamaytiradi.
cProfile — butun dastur qayerda vaqt sarflaydi#
Mana real misol — matn korpusidan lug'at quruvchi kod (6-bob amaliyotiga o'xshash):
# vocab.py
import re
from collections import Counter
def tokenize(text):
return re.findall(r"\w+", text.lower())
def build_vocab(docs, stop_words):
counts = Counter()
for doc in docs:
for tok in tokenize(doc):
if tok not in stop_words:
counts[tok] += 1
return counts
def main():
docs = ["Python ML uchun eng mashhur til va u juda qulay"] * 20000
stop_words = ["va", "u", "uchun", "eng", "juda"] * 200 # ro'yxat
build_vocab(docs, stop_words)
if __name__ == "__main__":
main()python -m cProfile -s cumtime vocab.py 120139 function calls (120135 primitive calls) in 0.374 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.374 0.374 vocab.py:15(main)
1 0.344 0.344 0.374 0.374 vocab.py:7(build_vocab)
20000 0.004 0.000 0.030 0.000 vocab.py:4(tokenize)
20000 0.017 0.000 0.017 0.000 {method 'findall' of 're.Pattern' objects}O'qish: tottime — funksiyaning o'zida o'tgan vaqt (chaqirgan
funksiyalarisiz), cumtime — hammasi bilan. build_vocabning o'zi 0.344 s
— regex (tokenize) atigi 0.030 s. Demak muammo regex'da emas, siklning
o'zida — aniqrog'i tok not in stop_words qatorida: stop_words —
1000 elementli ro'yxat, har tekshiruv O(n).
Bitta o'zgarish:
stop_words = set(["va", "u", "uchun", "eng", "juda"] * 200) # set — O(1) tekshiruv 120139 function calls (120135 primitive calls) in 0.044 seconds8.5 baravar tezroq — bitta so'z bilan. Regex'ni "optimallashtirishga" vaqt sarflaganingizda, natija deyarli o'zgarmas edi. Profiler bo'lmasa, buni taxmin qilish qiyin.
Vizual tahlil uchun: uv add --dev snakeviz → python -m cProfile -o prof.out vocab.py
→ snakeviz prof.out. Qatorma-qator o'lchash uchun — line_profiler;
ishlab turgan jarayonni tekshirish uchun — py-spy (kodni o'zgartirmasdan).
tracemalloc — xotira#
import tracemalloc
tracemalloc.start()
data = [i * i for i in range(1_000_000)]
current, peak = tracemalloc.get_traced_memory()
print(f"joriy: {current / 1e6:.1f} MB, cho'qqi: {peak / 1e6:.1f} MB") # ~40 MB
tracemalloc.stop()Million son — 40 MB (2-bob: har int — obyekt). NumPy'da — 8 MB. Generator bilan (7-bob) — deyarli nol.
3. Algoritmik murakkablik — eng katta yutuqlar shu yerda#
Big-O — ma'lumot hajmi oshganda vaqt qanday o'sishi. Aniq soniyalar emas, o'sish tezligi:
| Murakkablik | Nomi | n = 1 000 | n = 1 000 000 | Misol |
|---|---|---|---|---|
| O(1) | Doimiy | 1 | 1 | dict[k], x in set, lst[i] |
| O(log n) | Logarifmik | 10 | 20 | bisect (5-bob) |
| O(n) | Chiziqli | 1 000 | 1 000 000 | x in list, sum, bitta sikl |
| O(n log n) | 10 000 | 20 000 000 | sorted() | |
| O(n²) | Kvadratik | 1 000 000 | 10¹² — soatlar | Ichma-ich sikl, siklda x in list |
Python tuzilmalari amallarining narxi (5–6-boblar xulosasi):
| Amal | list | dict / set | deque |
|---|---|---|---|
Indeks bo'yicha [i] | O(1) | — | O(n) |
| Oxiriga qo'shish | O(1) | O(1) | O(1) |
| Boshiga qo'shish / boshidan olish | O(n) | — | O(1) |
x in ... | O(n) | O(1) | O(n) |
| Kalit bo'yicha olish | — | O(1) | — |
| Saralash | O(n log n) | — | — |
Eng ko'p uchraydigan O(n²) tuzoqlari:
# 1. Siklda ro'yxatdan qidirish
for user in users: # n
if user.id in banned_ids_list: # × n → O(n²)
...
banned = set(banned_ids_list) # ✅ bir marta O(n), keyin har tekshiruv O(1)
# 2. Siklda satr yig'ish (3-bob)
result = ""
for part in parts:
result += part # har safar yangi satr — 100k bo'lakda ~10× sekinroq
result = "".join(parts) # ✅
# 3. Siklda pop(0)
while queue:
item = queue.pop(0) # O(n) har safar
queue = deque(queue) # ✅ popleft() — O(1)
# 4. Ikki ro'yxatni "birlashtirish" ichma-ich sikl bilan
for order in orders:
for user in users:
if order.user_id == user.id: ...
users_by_id = {u.id: u for u in users} # ✅ lug'at indeksi, keyin O(1) qidiruvOxirgisi — Pandas'dagi merge (20-bob) ichkarida aynan shunday ishlaydi.
4. Tezlashtirish usullari — samaradorlik tartibida#
| Usul | Odatiy yutuq | Bob |
|---|---|---|
| To'g'ri algoritm / ma'lumot tuzilmasi | 10–10 000× | 5, 6, 25 |
| Vektorlashtirish (NumPy/Pandas) | 10–100× | 19, 20 |
| Keraksiz ishni qilmaslik: keshlash, erta to'xtatish, dangasalik | 2–1000× | 7, 8, 14 |
| I/O parallelligi (async, threads) — LLM, tarmoq | so'rovlar soniga proporsional | 17 |
| CPU parallelligi (process'lar) | yadrolar soniga yaqin | 17 |
Tayyor tez kutubxona (polars, orjson, numba) | 2–50× | — |
| Mikro-optimallashtirish (lokal o'zgaruvchi, metodni keshlash) | 5–20% | — |
Keshlash#
from functools import lru_cache
@lru_cache(maxsize=10_000)
def embed(text: str) -> tuple[float, ...]: # tuple — hashlanadi va o'zgarmas
return tuple(call_embedding_api(text)) # bir xil matn uchun API qayta chaqirilmaydiLLM ilovalarida keshlash — tezlik va pul: bir xil savollar uchun javob keshi (14-bobdagi disk keshi), embedding keshi, prompt caching (23-bob).
Python'dan tashqariga chiqish#
Profil ko'rsatsa-yu, sof Python sikli baribir sekin bo'lsa:
- NumPy/Pandas'ga o'tkazing (deyarli har doim birinchi variant);
- Polars — Pandas'ga o'xshash, Rust'da yozilgan, ko'p hollarda 5–20× tez;
- Numba —
@njitdekoratori bilan sonli funksiyani mashina kodiga kompilyatsiya; - Cython / Rust (PyO3) — eng og'ir holatlar uchun.
ML'da esa og'ir hisob baribir GPU'da (PyTorch) bo'ladi — Python faqat boshqaradi (1-bob, "yelim til").
5. Professional kod — o'zingizni tekshiring#
Kod faqat ishlashi kerak emas — uni boshqalar (va 6 oydan keyingi siz) o'qishi, o'zgartirishi va unga ishonishi kerak. Har bir loyihangizni shu ro'yxat bo'yicha tekshiring:
| Mezon | Savol | Bob |
|---|---|---|
| Muhit | uv sync bilan har qanday kompyuterda bir xil muhit tiklanadimi? | 9 |
| Tuzilma | src-layout, mantiqiy modullar, __main__ himoyasi? | 9 |
| Nomlar | Funksiya nomi nima qilishini aytadimi? Sehrli satr/sonlar yo'qmi? | 8, 13 |
| Funksiyalar | Har biri bitta vazifa, qisqa, yon ta'sirsiz? | 8 |
| Tiplar | Type hint'lar, mypy o'tadi? Tashqi ma'lumot — Pydantic? | 15 |
| Xatolar | Aniq istisnolar, except: pass yo'q, tushunarli xabarlar? | 10 |
| Loglar | print emas logging; sirlar logda yo'q? | 10 |
| Testlar | Muhim mantiq testlangan, tashqi API'lar fake bilan? | 16 |
| Sifat | ruff check, ruff format, pre-commit, CI? | 16 |
| Takrorlanuvchanlik | Seed'lar, versiyalar, konfiguratsiya saqlanadimi? | 18, 22 |
| Xavfsizlik | Kalitlar .envda, SQL parametrli, pickle ishonchsiz manbadan emas, LLM chiqishiga ko'r-ko'rona ishonch yo'q? | 9, 11, 18, 23 |
| Hujjat | README: nima qiladi, qanday o'rnatiladi, qanday ishlatiladi? | — |
6. Kurs bo'yicha o'z-o'zini tekshirish#
Quyidagi savollarga kodni ochmasdan javob bera olsangiz — Python poydevoringiz ML/AI uchun tayyor:
Obyektlar va xotira
b = adan keyina.append(1)negabni ham o'zgartiradi,a = a + [1]esa yo'q? Mutable default argument nega xavfli?To'plamlar
Million elementli ro'yxatdax in lstva to'plamdax in sfarqi nima va nega? Qaysi tiplar lug'at kaliti bo'la oladi?Iteratorlar
Generator ikkinchi marta aylanilganda nima bo'ladi? 50 GB faylni xotiraga sig'dirmasdan qanday qayta ishlaysiz?Funksiyalar
Closure nima va sikldagi lambda'lar nega oxirgi qiymatni "ko'radi"? Dekorator qanday yoziladi?OOP
__eq__yozilsa__hash__ga nima bo'ladi?super().__init__()nega kerak? Dataclass va Pydantic qachon?Xatolar
raise ... from enima beradi? Qaysi HTTP xatolarida qayta urinish kerak?Parallellik
GIL nima va qachon threadlar yordam beradi? 1000 ta LLM so'rovini limit bilan qanday parallel yuborasiz?NumPy/Pandas
Broadcasting qoidasi? View va copy farqi?df[mask]['col'] = xnega ishlamaydi?ML ish jarayoni
Data leakage nima, qanday oldini olasiz? Nega test qismiga faqat bir marta qaraladi?LLM
stop_reasonqiymatlari nimani bildiradi? Tool use sikli qanday ishlaydi? Prompt caching qachon ishlamaydi?
Javob bera olmagan savolingiz bo'lsa — tegishli bobga qayting va misollarni REPL'da qayta yozib ko'ring.
7. Yo'l xaritasi: bu kursdan keyin#
Python — poydevor. Keyingi qadamlar yo'nalishingizga qarab:
ML Engineering yo'li#
| Bosqich | Mavzular | Vositalar |
|---|---|---|
| 1. Klassik ML | Regressiya, daraxtlar, ansambllar, klasterlash, xususiyatlar muhandisligi, baholash | scikit-learn, XGBoost/LightGBM |
| 2. Deep learning | Neyron tarmoqlar, backprop, optimizatorlar, CNN, RNN, Transformer | PyTorch |
| 3. NLP / LLM | Tokenizatsiya, embedding'lar, fine-tuning, LoRA | Hugging Face Transformers, PEFT |
| 4. MLOps | Tajribalarni kuzatish, model registri, deploy, monitoring | MLflow / W&B, Docker, FastAPI |
| 5. Masshtab | GPU, distributed training, ma'lumotlar pipeline'lari | PyTorch DDP, Ray, Spark |
AI Engineering yo'li#
| Bosqich | Mavzular | Vositalar |
|---|---|---|
| 1. LLM API'lar | Prompt engineering, structured output, streaming, narx va kechikish | Anthropic/OpenAI SDK (23-bob) |
| 2. RAG | Chunking, embedding'lar, vektor qidiruv, reranking, baholash | NumPy (19-bob), pgvector/Qdrant |
| 3. Agentlar | Tool use, rejalashtirish, xotira, ko'p agentli tizimlar, MCP | SDK tool runner, Claude Agent SDK |
| 4. Eval | Oltin datasetlar, LLM-as-judge, regressiya testlari | pytest (16-bob), Pandas (20-bob) |
| 5. Production | Kuzatuv, xavfsizlik (prompt injection), xarajat, keshlash, rate limit | FastAPI (24-bob), Redis, OpenTelemetry |
aidoc.uz'dagi boshqa kitoblar shu yo'lni davom ettiradi: "AI Engineering — 0 dan boshlab", "OpenAI API bilan ishlash", "AI agentlar qurish" va "AI agentlarni amaliyotda qurish". Endi ulardagi har bir kod misolini to'liq tushunasiz.
8. Yakuniy loyiha#
O'rganganlaringizni birlashtiruvchi loyiha — portfoliongizning birinchi jiddiy ishi bo'lishi mumkin:
Yakuniy loyiha: o'zbekcha sharhlar tahlili platformasi
Maqsad: o'zbekcha mahsulot sharhlarini tasniflaydigan va tahlil qiladigan servis.
- Dataset (11, 20-boblar): kamida 300 ta sharh (o'zingiz yozing, ochiq manbalardan yig'ing yoki LLM bilan yarating va qo'lda tekshiring). Tozalash: apostroflar, dublikatlar, bo'sh qatorlar. JSONL formatda, train/test bo'linishi bilan.
- Baseline model (22-bob): TF-IDF + LogisticRegression, o'zbekcha tokenizatsiya bilan. CV natijasi va test'dagi classification report.
- LLM tasnifchi (17, 23-boblar): Claude bilan structured output
(
sentiment,topics,summary), async + Semaphore bilan butun test qismini tasniflash, narx va kechikishni hisoblash. - Solishtirish (20, 21-boblar): ikkala yondashuv uchun aniqlik, narx, kechikish jadvali va grafiklar. Qaysi holatda qaysi biri afzal — yozma xulosa.
- Servis (24-bob): FastAPI —
/classify(tezkor baseline),/analyze(LLM, streaming bilan), API kaliti, kirish cheklovlari. - Sifat (15, 16-boblar): type hint'lar + mypy, kamida 20 ta test (LLM — fake bilan), ruff, pre-commit, GitHub Actions.
- Hujjat: README — arxitektura sxemasi, o'rnatish, natijalar jadvali.
Maslahatni ko'rsatish
Har bir qismni alohida boblar bilan bog'lang: dataset — 11, 20; model — 22; LLM — 17, 23; servis — 24; sifat — 15, 16. Avval eng sodda ishlaydigan versiya (end-to-end), keyin yaxshilang.
9. Xayrlashuv o'rniga#
Dasturlashni o'rganishning yagona yo'li — dasturlash. Bu kursdagi har bir bob — xarita, lekin yo'lni oyog'ingiz bilan bosib o'tishingiz kerak: mashqlarni yeching, xato qiling, traceback'larni o'qing, profiler bilan o'lchang, testlar yozing, loyihalar quring.
Ikki maslahat:
- Har kuni oz-ozdan kod yozing. Haftada bir marta 7 soat emas — har kuni 1 soat. Ko'nikma takrorlash bilan mustahkamlanadi.
- AI yordamchilardan to'g'ri foydalaning. Ular kod yozishni
tezlashtiradi, lekin siz kodni tushunishingiz va tekshira
olishingiz kerak. Bu kurs aynan shuning uchun: AI yozgan kodda
mutable default, data leakage,
except: passyoki prompt injection teshigini ko'ra oladigan muhandis — AI davrining eng qadrli mutaxassisi.
Omad! 🚀
- 01Avval to'g'ri, keyin o'lchang (timeit, cProfile, tracemalloc), keyin eng katta muammoni tuzating.
- 02Eng katta yutuqlar — algoritm va ma'lumot tuzilmasidan: siklda list'dan qidirish o'rniga set/dict.
- 03Keyingi qadamlar: vektorlashtirish, keshlash, parallellik; mikro-optimallashtirish — oxirida.
- 04Professional kod: takrorlanuvchan muhit, tiplar, testlar, loglar, xavfsizlik, hujjat.
- 05ML Engineering: klassik ML → PyTorch → Transformers → MLOps; AI Engineering: LLM API → RAG → agentlar → eval → production.
- 06Yakuniy loyiha — kursning barcha qismlarini birlashtirib, portfolio boshlang.
Mustahkamlash
Test va amaliy masalalar
Avval testni ishlang — har javobdan keyin izoh chiqadi. Keyin masalalarni shu yerning o'zida yechib, brauzerdagi haqiqiy Python bilan avtomatik tekshiring. Natijalaringiz kurs progressi sahifasida jamlanadi.
Bilimni tekshirish
Bob bo'yicha test
12 ta savol · har javobdan keyin to'g'ri yoki xatoligi va izoh ko'rsatiladi · oxirida natija foizda.
Amaliy masalalar
Kodni yozing va «Tekshirish»ni bosing (yoki Ctrl/⌘ + Enter). Kodingiz shu brauzerda saqlanib turadi.
01Tartibni saqlagan holda dublikatlarni olib tashlash (tez)
dedupe(items) — birinchi uchragan tartibni saqlab dublikatlarni olib tashlasin. O(n) bo'lishi kerak: if x not in natija_royxati (O(n²)) yondashuvi 200 000 element uchun juda sekin — test vaqtni ham tekshiradi.
02Ikki son yig'indisi (O(n))
two_sum(nums, target) — yig'indisi target ga teng ikki turli element indekslarini (i, j) (i < j) qaytarsin, yo'q bo'lsa None. Ichma-ich sikl emas — lug'at bilan bir o'tishda.
03Memoizatsiya
count_paths(rows, cols) — rows × cols to'rning chap-yuqori burchagidan o'ng-pastki burchagiga faqat o'ngga yoki pastga yurib nechta yo'l borligini rekursiya + functools.lru_cache bilan hisoblasin. count_paths(18, 18) bir zumda.