01. Nega JSON Yirik Loyihalarda O'ladi?
gRPC & High-Performance System Design
01. Nega JSON Yirik Loyihalarda O'ladi? Benchmarklar va Real Muammolar
"JSON insonlar o'qishi uchun ajoyib, ammo protsessorlar va mobil tarmoqlar uchun haqiqiy fojiadir." — Martin Kleppmann, 'Designing Data-Intensive Applications' muallifi.
Ko'pgina dasturchilar o'z faoliyatini REST API va JSON bilan boshlaydi. Startup yoki kichik ilovalarda bu a'lo darajada ishlaydi. Biroq foydalanuvchilar soni millionlarga yetganda, qidiruv natijalari, jonli xaritalar yoki doimiy chat xabarlari almashilganda, JSON ko'rinmas qotilga aylanadi.
Keling, nima uchun dunyoning yetakchi kompaniyalari (Telegram, Uber, Netflix, Google, Meta) ichki tarmoq va mobil ulanishlarda JSON'dan butunlay voz kechganini texnik jihatdan tahlil qilamiz.
1. JSON ning 3 Ta Yashirin Qotili
1. String Parsing va CPU Cycle Churn (O'g'irlangan Vaqt)
JSON — bu matn (ASCII/UTF-8 string). Protsessor JSON'ni o'qiyotganda baytma-bayt skanerlashga majbur:
- Qavs qayerda ochildi?
{ - Qo'shtirnoq qayerda yopildi?
" - Probel yoki yangi qator bormi?
\n - Raqam qayerda tugaydi?
Bu jarayon protsessorning L1/L2 keshini to'ldiradi va ko'plab Branch Misprediction'larga sabab bo'ladi.
JSON (Matn): { "age" : 25 } --> Protsessor 14 ta baytni tahlil qilib, '2' va '5' ni int ga aylantirishi kerak.
Binar (Protobuf): [0x08, 0x19] --> Protsessor atigi 2 baytni to'g'ridan-to'g'ri registrga yuklaydi!
2. Mobil Xotiradagi Falokat: Heap Allocation va GC Pressure
Smartfonlarda RAM cheklangan. iOS (Swift) yoki Android (Kotlin) da JSONDecoder 10,000 ta obyektdan iborat feedni o'qiyotganda:
- Butun JSON matni xotiraga yuklanadi (~15 MB).
- Parslash paytida yuz minglab vaqtinchalik
String,SubstringvaDictionaryobyekti xotirada (Heap) yaratiladi. - Heap fragmentatsiyasi yuzaga keladi va iOS'da Jetsam (Memory Warning) ilovangizni majburan o'ldiradi (Crash). Android'da esa Garbage Collector (GC) ekranni 120 FPS dan 30 FPS ga tushirib, jank (qotish) keltirib chiqaradi.
3. Ortiqcha Shishgan Baytlar (Payload Bloat)
JSON har bir obyektda kalit nomlarini qayta-qayta takrorlaydi:
[
{"user_id": 101, "transaction_status": "COMPLETED", "amount_cents": 50000},
{"user_id": 102, "transaction_status": "COMPLETED", "amount_cents": 25000},
{"user_id": 103, "transaction_status": "COMPLETED", "amount_cents": 120000}
]
"transaction_status" so'zining o'zi 20 bayt! Agar 10,000 ta tranzaksiya kelsa, tarmoq orqali birgina kalit so'zining o'zi uchun 200 KB keraksiz axlat o'tadi.
Binar protokollarda (Protobuf/TL) esa kalit nomi o'rniga atigi 1 baytlik Field Tag (masalan 2) ishlatiladi.
2. Haqiqiy Laboratoriya Benchmarki (Apple M-Series & Go)
Bir xil ma'lumotlar to'plami (100,000 ta yirik profil obyekti) ustida o'tkazilgan benchmark natijalari:
| Metrika | REST (JSON) | gRPC (Protobuf v3) | Yutuq (Improvement) |
|---|---|---|---|
| Tarmoq Hajmi (Wire Size) | 48.6 MB | 11.2 MB | 4.3x kichikroq |
| Serializatsiya (Encoding) | 142 ms | 19 ms | 7.4x tezroq |
| Deserializatsiya (Decoding) | 186 ms | 16 ms | 11.6x tezroq |
| Xotira sarfi (RAM Churn) | 64.2 MB | 4.1 MB | 15.6x tejamkor |
| CPU sarfi (Batareya quvvati) | Yuqori (Issiqlik) | Minimal | Batareya 3x kamroq ketadi |
[Deserializatsiya Vaqti Taqqoslash]
JSON: ████████████████████ 186 ms
Protobuf: █ 16 ms (11x tezroq!)
3. "AHA!" Moment: Dasturchi Ko'zi Bilan
"Tasavvur qiling, siz yuk mashinasida yuk tashiysiz. JSON — bu mebellarni yig'ilgan holatida yuklash (juda ko'p bo'sh havo tashiysiz). Protobuf esa IKEA uslubida — hamma narsa ixcham qutilarda, raqamlar bilan kodlangan."
Mobil ilovangizda foydalanuvchi tunnelga kirganda yoki EDGE/3G tarmoqda bo'lganda, 50 KB lik JSON 3-4 soniyada yuklanadi. 10 KB lik Protobuf esa 300 millisekundda ochiladi. Foydalanuvchi uchun ilovangiz "uchar"dek tuyuladi!
Keyingi darsda biz ushbu binar formatning asosi bo'lgan Protocol Buffers v3 va gRPC qanday ishlashini Swift va Go kodlari orqali to'liq ko'rib chiqamiz.