Azimjon Abdurasulov

03. FlatBuffers: 0 ms Parslash va Zero-Copy

gRPC & High-Performance System Design

03. FlatBuffers: 0 ms Parslash va Xotira Mo'jizasi (Zero-Copy)

"Eng tez kod — bu umuman ishlamaydigan koddur. Eng tez deserializatsiya — bu umuman deserializatsiya qilmaslikdir."

Oldingi darsda biz Protobuf qanday qilib JSON'dan 10 barobar tez ishlashini ko'rdik. Ammo Protobuf'da ham bir cheklov bor: u baribir binar baytlarni o'qib, xotirada yangi obyekt (struct yoki class) yaratadi (Deserialization).

Agar sizda sekundiga 60 ta kadr (60 FPS) chizilishi kerak bo'lgan o'yin, xaritadagi minglab taksilar harakati yoki 1 millionta obyekt bo'lsa-chi? Bu yerda sahnaga Google FlatBuffers (va Cap'n Proto) chiqadi!


1. Zero-Copy (Nol Nusxa) Nima Degani?

Oddiy tizimlarda ma'lumotlar oqimi:

Tarmoq (Socket) ---> Binar Baytlar ---> [PARSER / DECODER] ---> Xotirada Yangi Obyektlar (Heap Allocations)

FlatBuffers Zero-Copy tizimida:

Tarmoq (Socket) ---> Binar Baytlar (RAM ga yuklanadi)
                                 ^
                                 |  To'g'ridan-to'g'ri ko'rsatkich (Pointer Offset)
[Sizning Kodingiz] ---------------+  (0 ms, 0 bayt yangi RAM!)

FlatBuffers ma'lumotlarni xotiraga shunday joylashtiradiki, siz ularni deserializatsiya qilmasdan, to'g'ridan-to'g'ri binar massiv ustidan o'qiysiz!


2. FlatBuffers Sxemasi (.fbs)

// monster.fbs
namespace GameEngine;

enum Color:byte { Red = 0, Green, Blue = 2 }

table Vec3 {
  x:float;
  y:float;
  z:float;
}

table Monster {
  pos:Vec3;
  mana:short = 150;
  hp:short = 100;
  name:string;
  inventory:[ubyte];
  color:Color = Blue;
}

root_type Monster;

3. Swift 6 da Zero-Copy O'qish

Qarang, hech qanday JSONDecoder().decode(...) yoki try Monster(serializedBytes: ...) yo'q!

import Foundation
import FlatBuffers

// 1. Tarmoqdan kelgan xom baytlar
let rawBytes: [UInt8] = networkPacketData

// 2. ByteBuffer yaratiladi (hech qanday xotira ko'chirilmaydi!)
var byteBuffer = ByteBuffer(bytes: rawBytes)

// 3. To'g'ridan-to'g'ri ko'rsatkich orqali o'qish
let monster = Monster.getRootAsMonster(bb: byteBuffer)

// 4. Qiymatlarni chaqirish (VTable offset orqali O(1) vaqtda olinadi)
print("Monstr nomi: \(monster.name ?? "")")
print("HP: \(monster.hp)")
print("Pozitsiya X: \(monster.pos?.x ?? 0)")

Bu Nega Mo'jiza?

Agar sizga 100 megabaytlik ma'lumot kelsa va sizga undan faqatgina bitta foydalanuvchining ismi kerak bo'lsa:

  • JSON: 100 MB li matnning hammasini boshidan oxirigacha o'qib chiqishga majbur (2-3 soniya ketadi).
  • Protobuf: 100 MB li binar faylning barcha maydonlarini xotiraga nusxalaydi (200-300 ms).
  • FlatBuffers: Xotiradan faqat kerakli maydonning bayt manziliga sakraydi va uni o'qiydi (0.0001 ms!).

4. Benchmark: Protobuf vs FlatBuffers vs JSON

1,000,000 ta murakkab obyektni o'qish tezligi:

XususiyatREST (JSON)Protobuf v3FlatBuffers (Zero-Copy)
Deserializatsiya Vaqti1,850 ms160 ms0.02 ms (Instant!)
Xotira Ajratish (Allocations)~120 MB~18 MB0 Bayt (Zero Allocations)
Oldinga/Orqaga MoslikMavjudJuda qulayJuda qulay (VTable)
Foydalanish SohalariOddiy WebMicroservices, gRPCO'yinlar, AI modellar, Yuqori tezlik

5. Qachon Qaysi Birini Tanlash Kerak?

  • Protobuf + gRPC ni tanlang: Agar sizga mikroxizmatlararo aloqa, standart mobil API, qulay streaming va oson integratsiya kerak bo'lsa (Sanoat standarti).
  • FlatBuffers ni tanlang: Agar sizda o'yinlar (Unity/Unreal), real-vaqtli 3D render, TensorFlow Lite neyrotarmoq og'irliklari, yoki soniyasiga millionlab binar voqealar oqimi bo'lsa.
  • JSON ni tanlang: Faqat tashqi public API yoki oddiy CMS saytlar uchun.

Markdown manba

iOS Lessons