?? AcBinary vs MessagePack

Komplett Benchmark Összehasonlítás + Memória Diagnosztika
Generálva: 2024. december 13. | .NET 9.0 | Intel Core i7-10750H

??? Teszt Környezet

?? Windows 11 (23H2) ?? Intel Core i7-10750H @ 2.60GHz ?? .NET SDK 10.0.101 ?? Runtime: .NET 9.0.11 ?? BenchmarkDotNet v0.15.2 ?? Teszt adat: 3×3×3×4 hierarchia

?? Méret Összehasonlítás

18.9 KB
AcBinary WithRef
15.8 KB
AcBinary NoRef
11.2 KB
MessagePack

Méret arány (MessagePack = 100%)

AcBinary: 168%
MsgPack: 100%
AcBinary
MessagePack
?? Megjegyzés: Az AcBinary nagyobb méretet eredményez a beépített metaadat (property nevek táblája) és típusinformációk miatt, ami viszont lehetõvé teszi a schema evolúciót és a gyorsabb deszerializálást.

? Teljesítmény Összehasonlítás

Mûvelet AcBinary MessagePack Arány Eredmény
Serialize WithRef 84.20 ?s 18.84 ?s 4.47× MsgPack gyorsabb
Serialize NoRef 70.18 ?s 18.84 ?s 3.73× MsgPack gyorsabb
Deserialize WithRef 40.10 ?s 41.10 ?s 0.98× AcBinary gyorsabb
Deserialize NoRef 1.02 ?s 41.10 ?s 0.025× 40× gyorsabb!
Populate 39.27 ?s Csak AcBinary
PopulateMerge 40.73 ?s Csak AcBinary

?? Memória Allokáció (GC Diagnosztika)

Mûvelet AcBinary MessagePack Gen0 Gen1 Értékelés
Serialize WithRef 55.34 KB 12.50 KB 9.03 4.43× több
Serialize NoRef 46.30 KB 12.50 KB 7.45 3.70× több
Deserialize WithRef 38.17 KB 26.24 KB 6.23 0.43 1.45× több
Deserialize NoRef 2.85 KB 26.24 KB 0.47 0.004 9× kevesebb!
?? GC Pressure: A Serialize WithRef 9.03 Gen0 GC-t triggerel 1000 mûveletre. Ez jelentõs GC nyomást jelent nagy áteresztõképességû szerver alkalmazásokban.

?? Memória Allokációs Hotspotok

Serialize (55.34 KB allokáció)

Forrás Becsült méret Leírás
ToArray() ~19 KB Végsõ byte[] allokáció a visszatérési értékhez
Dictionary<object,int> ~8 KB Reference scanning: _scanOccurrences, _writtenRefs
HashSet<object> ~4 KB Multi-referenced objektumok nyilvántartása
Dictionary<string,int> ~6 KB Property name table + string interning
List<string> ~4 KB Property nevek és interned stringek listái
Boxing ~10 KB Value type boxing a property getter-ekben
Egyéb ~4 KB Closure-ok, delegate-ek, átmeneti objektumok

?? További Optimalizálási Lehetõségek

MAGAS HATÁS 1. IBufferWriter<byte> alapú Serialize

A ToArray() hívás ~19 KB allokációt okoz. Ehelyett IBufferWriter<byte> interfész használatával a hívó biztosíthatja a buffert, elkerülve az allokációt.

Becsült megtakarítás: ~35% memória csökkenés serialize-nál

MAGAS HATÁS 2. Typed Property Getter-ek (Boxing elkerülése)

A jelenlegi Func<object, object?> getter minden value type-ot boxol. Típusos getter-ek (Func<T, int>, stb.) használatával megszüntethetõ.

Becsült megtakarítás: ~10 KB / serialize (~18% csökkenés)

KÖZEPES HATÁS 3. Reference Tracking gyûjtemények poolozása

A Dictionary és HashSet objektumok a context pool-ban maradnak, de Clear() után is megtartják a kapacitásukat. A poolban tárolás elõtt érdemes lenne TrimExcess() hívni, vagy kisebb initial capacity-t használni.

Becsült megtakarítás: ~5 KB / serialize

KÖZEPES HATÁS 4. String.Create() UTF8 kódoláshoz

A deszerializálásnál a Encoding.UTF8.GetString() új stringet allokál. String.Create() span callback-kel közvetlenül a string bufferbe írhat.

Becsült megtakarítás: ~2 KB / deserialize komplex objektumoknál

ALACSONY HATÁS 5. Two-pass serialize elkerülése NoRef módban

NoRef módban is fut a CollectPropertyNames fázis a metaadathoz. Ha a típus ismert és stabil, a property nevek elõre cache-elhetõk.

Becsült megtakarítás: ~10% sebesség javulás NoRef serialize-nál

ALACSONY HATÁS 6. Span-based enum serialization

A Convert.ToInt32(value) enum értékeknél boxing-ot okoz. Típusos enum kezelés vagy Unsafe.As használatával elkerülhetõ.

Becsült megtakarítás: ~24 byte / enum érték

?? Funkció Összehasonlítás

Funkció AcBinary MessagePack Megjegyzés
Reference Handling ($id/$ref) ? ? Közös objektumok deduplikálása
Populate (meglévõ objektum) ? ? Létezõ objektum frissítése
PopulateMerge (IId merge) ? ? Lista elemek ID alapú merge
Schema Evolution ? ?? Property név alapú mapping
Metadata Table ? ? Property nevek indexelése
String Interning ? ? Ismétlõdõ stringek deduplikálása
Kompakt méret ?? ? MsgPack ~40% kisebb
Serialize sebesség ?? ? MsgPack 3-4× gyorsabb
Deserialize sebesség ? ?? AcBinary akár 40× gyorsabb

?? Mikor Melyiket Használd?

?? AcBinary ajánlott

  • Deserialize-heavy workload (kliens oldal)
  • Populate/Merge szükséges
  • Reference handling kell (shared objects)
  • Schema változások várhatóak
  • NoRef mód használható (40× gyorsabb!)

?? MessagePack ajánlott

  • Serialize-heavy workload (szerver oldal)
  • Méret kritikus (hálózati átvitel)
  • Egyszerû objektumok (nincs referencia)
  • Külsõ rendszerekkel kompatibilitás
  • Minimális GC pressure kell

?? Kiemelt Eredmények

40×
AcBinary NoRef Deserialize gyorsabb
Kevesebb memória (NoRef Deser.)
3.7×
MsgPack Serialize gyorsabb
4.4×
Több memória (Serialize WithRef)

?? Összegzés

AcBinary erõsségei:

  • Kiemelkedõen gyors deserializálás, különösen NoRef módban (40× gyorsabb)
  • Beépített reference handling és populate/merge támogatás
  • Schema evolution friendly (property név alapú)

Fejlesztendõ területek:

  • Serialize sebesség (3-4× lassabb MessagePack-nél)
  • Memória allokáció serialize-nál (4.4× több)
  • Output méret (~68% nagyobb)

Javasolt következõ lépések prioritás szerint:

  1. IBufferWriter<byte> támogatás hozzáadása
  2. Typed property getter-ek boxing elkerülésére
  3. Reference tracking collection pooling optimalizálása