VoidSentryUltimate – Extremely Fast SerDes Library

VoidSentryUltimate

Github
Docs
Wally
Pesde
Npm
Creator Store

VoidSentryUltimate is a schematized serdes library, unlike my previous serdes libraries, this one is mainly focused on pure performance, and it has a lot of cool optimizations

Code example

local VoidSentryUltimate = require(path.to.VoidSentryUltimate)
local Types = VoidSentryUltimate.Types

local PlayerState = Types.Struct({
    Health = Types.U16,
    Name = Types.String8,
    Position = Types.Vector,
})

local encoded = VoidSentryUltimate.Serialize(PlayerState, {
    Health = 100,
    Name = "Builder",
    Position = Vector3.new(4, 8, 15),
})

local decoded = VoidSentryUltimate.Deserialize(PlayerState, encoded)
print(decoded.Name, decoded.Health)

According to my benchmarks, VoidSentryUltimate is 1.5-3x faster than sera on non-struct types(its a bit unfair), and pretty much equal on struct types

Why Use VoidSentryUltimate?

  • Rich Types Support – More than 40 types
  • Very Fast – Optimized for peak performance (bench results; benchmark)
  • Straightforward API

Why not use VoidSentryUltimate?

  • No schemaless serialization – You have to define the exact schema (if you want schemaless serialization, you might like VoidSentry2)
  • No runtime validations

Types Catalog

Primitives
Type Description
U8 / I8 1-byte unsigned / signed integer
U16 / I16 2-byte unsigned / signed integer
U24 / I24 3-byte unsigned / signed integer
U32 / I32 4-byte unsigned / signed integer
F16 2-byte reduced-precision float (lossy)
F24 3-byte reduced-precision float (lossy)
F32 4-byte float
F64 8-byte float
Bool One boolean in 1 byte
BoolPacked Exactly 8 booleans packed into 1 byte
String 2-byte length prefix, then 0–65,535 bytes
String8 1-byte length prefix, then 0–255 bytes
StringFixed(length) Exactly length bytes, no prefix
Buffer 2-byte length prefix, then 0–65,535 bytes
Buffer8 1-byte length prefix, then 0–255 bytes
Buffer24 3-byte length prefix, then 0–16,777,215 bytes
BufferFixed(length) Exactly length bytes, no prefix
Vector Vector3, three F32 (12 bytes)
VectorF16 Vector3, three F16 (6 bytes)
VectorF24 Vector3, three F24 (9 bytes)
VectorU8 / VectorI8 Vector3, three integers (3 bytes)
VectorU16 / VectorI16 Vector3, three integers (6 bytes)
VectorU24 / VectorI24 Vector3, three integers (9 bytes)
Collections
Type Description
Array(node) Array with 2-byte element count
Array8(node) Array with 1-byte element count
Array24(node) Array with 3-byte element count
ArrayFixed(node, length) Fixed length, no count prefix
Map(key, value) Map with 2-byte entry count
Map8(key, value) Map with 1-byte entry count
Map24(key, value) Map with 3-byte entry count
MapFixed(key, value, length) Fixed length, no count prefix
Struct(fields) Dense named fields, no struct prefix
DeltaStruct(fields) Sparse struct; u8 count/ids (max 255 present)
DeltaStruct16(fields) Sparse struct; u16 count/ids (max 65,535 present)
Optional(node) 1-byte presence marker + value when present
Roblox Types
Type Description
Vector2 Two F32 components (8 bytes)
Vector2F16 Two F16 components (4 bytes)
Vector2F24 Two F24 components (6 bytes)
Vector2U8 / Vector2I8 Two integers (2 bytes)
Vector2U16 / Vector2I16 Two integers (4 bytes)
Vector2U24 / Vector2I24 Two integers (6 bytes)
UDim2 Scale + offset as four F32 (16 bytes)
UDim2Scale Scale only as two F32 (8 bytes)
UDim2Offset Offset only as two F32 (8 bytes)
UDim2OffsetI16 Offset only as two I16 (4 bytes)
UDim2ScaleF24 Scale only as two F24 (6 bytes)
Color3 RGB as three bytes
Enum(enumType) Enum item value in 2 bytes
Enum8(enumType) Enum item value in 1 byte
CFrame Position + 3×3 matrix, 12×F32 (48 bytes)
CFrameF16 Same layout with F16 (24 bytes)
CFrameF24 Same layout with F24 (36 bytes)
QCFrame Position + quaternion, 7×F32 (28 bytes)
QCFrameF16 Same layout with F16 (14 bytes)
QCFrameF24 Same layout with F24 (21 bytes)
Instance 2-byte _VSID reference
Instance24 3-byte _VSID reference
SerInstance(className, schema) Serialize listed properties; deserialize via Instance.new

API Catalog

API Description
Serialize(schema, value) Encode into a new exactly sized buffer
Deserialize(schema, buffer) Decode from byte 0
SerializeWithOffset(schema, value, offset) Encode into a new buffer with offset zero bytes reserved up front
DeserializeWithOffset(schema, buffer, offset) Decode starting at offset
Push(schema, value, buffer, offset?) Encode into an existing buffer (default offset 0); buffer must already be large enough
SetWriteBufferSize(size) Resize the reusable serialize scratch buffer (default 1,000,000 bytes)
10 Likes

Just benched VoidSentryUltimate against Squash, Sera, Z, VoidSentry2, BlazeSentry, results:
Bench Repo

All libraries comparison (structs, primitives, cframes)

__________________________________________________
* RANKINGS (lower median μs is faster)
______________________________________
* TOP 6 OVERALL (all tests)
** #1 VoidSentryUltimate — 0.24μs med avg (57 tests)
** #2 Z — 0.25μs med avg (57 tests)
** #3 BlazeSentry — 0.29μs med avg (57 tests)
** #4 Sera — 0.30μs med avg (57 tests)
** #5 VoidSentry2 — 0.40μs med avg (57 tests)
** #6 Squash — 0.48μs med avg (57 tests)
______________________________________
* TOP 6 OVERALL — RoundTrip only
** #1 VoidSentryUltimate — 0.36μs med avg (19 tests)
** #2 Z — 0.38μs med avg (19 tests)
** #3 BlazeSentry — 0.44μs med avg (19 tests)
** #4 Sera — 0.45μs med avg (19 tests)
** #5 VoidSentry2 — 0.60μs med avg (19 tests)
** #6 Squash — 0.70μs med avg (19 tests)
______________________________________
* TOP 6 OVERALL — Serialize only
** #1 VoidSentryUltimate — 0.15μs med avg (19 tests)
** #2 BlazeSentry — 0.18μs med avg (19 tests)
** #3 Z — 0.18μs med avg (19 tests)
** #4 Sera — 0.21μs med avg (19 tests)
** #5 VoidSentry2 — 0.32μs med avg (19 tests)
** #6 Squash — 0.40μs med avg (19 tests)
______________________________________
* TOP 6 OVERALL — Deserialize only
** #1 Z — 0.20μs med avg (19 tests)
** #2 VoidSentryUltimate — 0.20μs med avg (19 tests)
** #3 Sera — 0.23μs med avg (19 tests)
** #4 BlazeSentry — 0.25μs med avg (19 tests)
** #5 VoidSentry2 — 0.28μs med avg (19 tests)
** #6 Squash — 0.32μs med avg (19 tests)
______________________________________
* TOP 6 — Number Types
** #1 VoidSentryUltimate — 0.05μs med avg (24 tests)
** #2 Z — 0.07μs med avg (24 tests)
** #3 BlazeSentry — 0.08μs med avg (24 tests)
** #4 VoidSentry2 — 0.09μs med avg (24 tests)
** #5 Sera — 0.10μs med avg (24 tests)
** #6 Squash — 0.15μs med avg (24 tests)
______________________________________
* TOP 6 — Number Types (RoundTrip)
** #1 VoidSentryUltimate — 0.08μs med avg (8 tests)
** #2 Z — 0.11μs med avg (8 tests)
** #3 BlazeSentry — 0.12μs med avg (8 tests)
** #4 VoidSentry2 — 0.15μs med avg (8 tests)
** #5 Sera — 0.15μs med avg (8 tests)
** #6 Squash — 0.20μs med avg (8 tests)
______________________________________
* TOP 6 — Other Primitives
** #1 VoidSentryUltimate — 0.08μs med avg (15 tests)
** #2 BlazeSentry — 0.11μs med avg (15 tests)
** #3 Z — 0.11μs med avg (15 tests)
** #4 VoidSentry2 — 0.12μs med avg (15 tests)
** #5 Sera — 0.13μs med avg (15 tests)
** #6 Squash — 0.22μs med avg (15 tests)
______________________________________
* TOP 6 — Other Primitives (RoundTrip)
** #1 VoidSentryUltimate — 0.12μs med avg (5 tests)
** #2 Z — 0.16μs med avg (5 tests)
** #3 BlazeSentry — 0.17μs med avg (5 tests)
** #4 VoidSentry2 — 0.18μs med avg (5 tests)
** #5 Sera — 0.20μs med avg (5 tests)
** #6 Squash — 0.31μs med avg (5 tests)
______________________________________
* TOP 6 — Vector Types
** #1 VoidSentryUltimate — 0.05μs med avg (3 tests)
** #2 Z — 0.07μs med avg (3 tests)
** #3 BlazeSentry — 0.08μs med avg (3 tests)
** #4 VoidSentry2 — 0.09μs med avg (3 tests)
** #5 Sera — 0.10μs med avg (3 tests)
** #6 Squash — 0.18μs med avg (3 tests)
______________________________________
* TOP 6 — Vector Types (RoundTrip)
** #1 VoidSentryUltimate — 0.07μs med avg (1 tests)
** #2 Z — 0.10μs med avg (1 tests)
** #3 BlazeSentry — 0.12μs med avg (1 tests)
** #4 VoidSentry2 — 0.14μs med avg (1 tests)
** #5 Sera — 0.14μs med avg (1 tests)
** #6 Squash — 0.27μs med avg (1 tests)
______________________________________
* TOP 6 — CFrame Types
** #1 VoidSentryUltimate — 0.10μs med avg (6 tests)
** #2 Z — 0.12μs med avg (6 tests)
** #3 BlazeSentry — 0.15μs med avg (6 tests)
** #4 Sera — 0.15μs med avg (6 tests)
** #5 VoidSentry2 — 0.17μs med avg (6 tests)
** #6 Squash — 0.32μs med avg (6 tests)
______________________________________
* TOP 6 — CFrame Types (RoundTrip)
** #1 VoidSentryUltimate — 0.14μs med avg (2 tests)
** #2 Z — 0.18μs med avg (2 tests)
** #3 BlazeSentry — 0.23μs med avg (2 tests)
** #4 Sera — 0.23μs med avg (2 tests)
** #5 VoidSentry2 — 0.25μs med avg (2 tests)
** #6 Squash — 0.48μs med avg (2 tests)
______________________________________
* TOP 6 — Struct Types
** #1 Z — 1.12μs med avg (9 tests)
** #2 VoidSentryUltimate — 1.16μs med avg (9 tests)
** #3 Sera — 1.24μs med avg (9 tests)
** #4 BlazeSentry — 1.29μs med avg (9 tests)
** #5 VoidSentry2 — 1.93μs med avg (9 tests)
** #6 Squash — 1.98μs med avg (9 tests)
______________________________________
* TOP 6 — Struct Types (RoundTrip)
** #1 Z — 1.69μs med avg (3 tests)
** #2 VoidSentryUltimate — 1.75μs med avg (3 tests)
** #3 Sera — 1.88μs med avg (3 tests)
** #4 BlazeSentry — 1.98μs med avg (3 tests)
** #5 VoidSentry2 — 2.91μs med avg (3 tests)
** #6 Squash — 2.99μs med avg (3 tests)
__________________________________________________

Maps & Arrays comparison (Sera is excluded since it doesnt support them)

__________________________________________________
* RANKINGS (lower median μs is faster)
______________________________________
* TOP 5 OVERALL (all tests)
** #1 VoidSentryUltimate — 0.80μs med avg (18 tests)
** #2 Z — 0.80μs med avg (18 tests)
** #3 BlazeSentry — 0.89μs med avg (18 tests)
** #4 VoidSentry2 — 1.56μs med avg (18 tests)
** #5 Squash — 1.75μs med avg (18 tests)
______________________________________
* TOP 5 OVERALL — RoundTrip only
** #1 VoidSentryUltimate — 1.20μs med avg (6 tests)
** #2 Z — 1.21μs med avg (6 tests)
** #3 BlazeSentry — 1.34μs med avg (6 tests)
** #4 VoidSentry2 — 2.37μs med avg (6 tests)
** #5 Squash — 2.64μs med avg (6 tests)
______________________________________
* TOP 5 OVERALL — Serialize only
** #1 VoidSentryUltimate — 0.54μs med avg (6 tests)
** #2 Z — 0.58μs med avg (6 tests)
** #3 BlazeSentry — 0.61μs med avg (6 tests)
** #4 VoidSentry2 — 1.43μs med avg (6 tests)
** #5 Squash — 1.57μs med avg (6 tests)
______________________________________
* TOP 5 OVERALL — Deserialize only
** #1 Z — 0.61μs med avg (6 tests)
** #2 VoidSentryUltimate — 0.66μs med avg (6 tests)
** #3 BlazeSentry — 0.70μs med avg (6 tests)
** #4 VoidSentry2 — 0.88μs med avg (6 tests)
** #5 Squash — 1.04μs med avg (6 tests)
______________________________________
* TOP 5 — Array Types
** #1 VoidSentryUltimate — 0.55μs med avg (9 tests)
** #2 BlazeSentry — 0.59μs med avg (9 tests)
** #3 Z — 0.60μs med avg (9 tests)
** #4 VoidSentry2 — 1.04μs med avg (9 tests)
** #5 Squash — 1.08μs med avg (9 tests)
______________________________________
* TOP 5 — Array Types (RoundTrip)
** #1 VoidSentryUltimate — 0.82μs med avg (3 tests)
** #2 BlazeSentry — 0.89μs med avg (3 tests)
** #3 Z — 0.89μs med avg (3 tests)
** #4 VoidSentry2 — 1.58μs med avg (3 tests)
** #5 Squash — 1.63μs med avg (3 tests)
______________________________________
* TOP 5 — Map Types
** #1 Z — 1.01μs med avg (9 tests)
** #2 VoidSentryUltimate — 1.05μs med avg (9 tests)
** #3 BlazeSentry — 1.18μs med avg (9 tests)
** #4 VoidSentry2 — 2.08μs med avg (9 tests)
** #5 Squash — 2.42μs med avg (9 tests)
______________________________________
* TOP 5 — Map Types (RoundTrip)
** #1 Z — 1.52μs med avg (3 tests)
** #2 VoidSentryUltimate — 1.58μs med avg (3 tests)
** #3 BlazeSentry — 1.80μs med avg (3 tests)
** #4 VoidSentry2 — 3.15μs med avg (3 tests)
** #5 Squash — 3.66μs med avg (3 tests)
__________________________________________________

TLDR; VoidSentryUltimate is overall fastest, Z slightly beats it in Structs and Maps

1 Like

ANYTHING but learning to use buffer library atp :sob: :folded_hands:
Its not that hard to divide stuff by 8 mentally

as an average low-level programmer this topic is made entirely out of words i do not understand

1 Like

what are those words you dont understand?

Good work, I’ll definitely use this in my upcoming projects.

1 Like

all of them, like i just said

what kinda name is VoidSentryUltimate tho

I just randomly came up with Voidsentry, and this library is pretty much a third rewrite of the original VoidSentry so I added Ultimate

v1.0.1

  • Added DeltaStruct, DeltaStruct16 types
  • Micro improvements

nice work, ill use this for sure

1 Like

V1.0.2:

  • Deserialize, DeserializeWithOffset, Push now return the cursor

pretty useful ill keep that in mind

im thinking on maybe adding more precision types (such as more quantized cframes, udim2, etc.), new schema object and micro optimizations (i missed some)