π» Ghost Serializer 1.3.0 β Unified JSON + YAML + Proto3 JSON runtime
This isn't an incremental bump from 1.2.7 β it's a rewrite of what "Ghost" ships as an artifact, plus the biggest decode-throughput jump in the project's history.
Highlights
- π One runtime, three wire formats. JSON, YAML, and Proto3 JSON now live in a single
ghost-serializationartifact.ghost-yaml,ghost-yaml-ktor, andghost-protobufare gone. - β‘ Decode throughput up to 1.2 GB/s. A rewritten decode hot path (in-order field prediction + SWAR scanning) pushed every channel well past 1.2.7 β String decode crosses 1 GB/s for the first time.
- π Kotlin/Wasm everywhere.
ghost-api,ghost-serialization,ghost-ktor, and the new Ghost Playground now shipwasmJstargets alongside JVM/Android/iOS. - πΉοΈ New Ghost Playground β Compose Multiplatform (JVM + Wasm) site with a live JSON/YAML/Proto Studio and a browser speed test vs
kotlinx.serializationand Moshi. - π Two silent data-corruption bugs fixed in the streaming reader and the WebFlux NDJSON decoder.
β‘ Performance: crossing 1 GB/s
Twitter macro fixture (631,514 bytes). Same 3 decode channels:
| Decode | 1.2.7 | 1.3.0 | Ξ 1.2.7β1.3.0 | vs KSER | vs Moshi |
|---|---|---|---|---|---|
| String | 0.803 GB/s | 1.229 GB/s Β· 514 Β΅s/op | +53% | +71% | +229% |
| Bytes | 0.698 GB/s | 1.052 GB/s Β· 600 Β΅s/op | +51% | +148% | +283% |
| Streaming | 0.304 GB/s | 0.529 GB/s Β· 1194 Β΅s/op | +74% | +174% | +24% |
(1.2.7 GB/s derived from its own published ops/s Γ the 631,514-byte Twitter fixture β same fixture in both versions; 1.2.7 didn't track GB/s directly.)
Three profile-driven changes got us here, each A/B-verified and kept only when it won:
- In-order field prediction β machine-generated JSON lists fields in declaration order, so the reader checks the predicted next field first instead of hashing every key. Biggest single win.
- SWAR whitespace + key comparison β 8 bytes at a time (
VarHandlewide load on JVM, scalar SWAR elsewhere). - SWAR value-string scan with deferred pool hash β branch-free 8-byte scan for quotes/backslash/control/non-ASCII; the string-pool hash is now only computed for strings short enough to actually pool.
Encode got targeted wins too (ASCII-prefix fast path +10%, BMP Unicode fast path +13% on the string channel). Full multi-engine tables: benchmarks.md.
π Unified runtime: JSON + YAML + Proto3 JSON
1.2.7 shipped three separate artifacts. 1.3.0 merges them into ghost-serialization:
// Before (1.2.x)
implementation("com.ghostserializer:ghost-yaml:1.2.x")
implementation("com.ghostserializer:ghost-yaml-ktor:1.2.x")
implementation("com.ghostserializer:ghost-protobuf:1.2.x")
// After β one runtime artifact
implementation("com.ghostserializer:ghost-serialization:1.3.0")
implementation("com.ghostserializer:ghost-ktor:1.3.0") // JSON + YAML + Proto adaptersOr apply id("com.ghostserializer.ghost") version "1.3.0" and let the Gradle plugin auto-inject adapters.
Full diff: v1.2.7...v1.3.0