Bson.luau | A BSON encoder and decoder

bson.luau


Github | Model

About

bson.luau is a BSON encoder and decoder implemented in pure luau.

What is BSON?

BSON (Binary JSON) is a binary format with JSON (JavaScript Object Notation) characteristic.

Usage

local bson = require("path/to/bson")

local Encoder = bson.Encoder
local Decoder = bson.Decoder

-- { hello = "world" }
print(Decoder.decode(Encoder.encode({ hello = "world" })))
11 Likes

What is the purpose behind it and why did you create it? I’m intrigued to find out what projects I could leverage ‘BSON’ on.

2 Likes

I choose to work with BSON because it can be decoded easily and quickly, and it also save space (although it can takes more space than JSON in some cases).

BSON is designed to be fast and efficient since it is encoded in binary rather than human readable text.

1 Like

Then how come I have never heard of it???

2 Likes

Not very well known in roblox community, although, the format is created by MongoDB team, so it’s well known somewhere else, like the Javascript community.

2 Likes

do objects, instances, Vectors, etc get serialized?

1 Like

Object do get serialized, everything else, no but i can work on that, BSON specification allows you to define custom binary format.

Although you can probably write your own serializer, bson.luau come preinstalled with BufferStream which should make it easier to work with binary data.

image

You sure?

View Test
local bson = require(workspace.BSON)

local Encoder = bson.Encoder
local Decoder = bson.Decoder
local Http = game.HttpService

local data = {Hello = "World"}

local iter = 1e4

game.LogService:ClearOutput()

task.wait(1)

local a = os.clock()

for i = 1, iter do
	Decoder.decode(Encoder.encode(data))
end

local b = os.clock()

for i = 1, iter do
	Http:JSONDecode(Http:JSONEncode(data))
end

local c = os.clock()

print(`{iter} iterations:`)
warn("BSON:", (b - a) * 1000, "ms")
warn("JSON:", (c - b) * 1000, "ms")
1 Like

The slowdown most definitely comes from using buffers. HttpService traps to a single engine function while working with buffers requires many library calls with extra sanity checks.

The result is a smaller binary than you’d get with a JSON string, but at the cost of being ~3x slower. This would be a viable option for DataStores, but using buffers is the fastest it can get.

I’m curious though, since many native implementations of Roblox APIs have seen tremendous speedups, maybe porting a JSON encoder/decoder to native luau could be faster?

HttpService is written in C++ so it would obviously be faster, maybe slapping some --!native’s around the module can give it a huge improvement and also 76ms isn’t even that long!

you lost me at “takes more space”

2 Likes

Come to think of it, there’s still more way to optimize it, like using parallel luau to decode each chunk.

It is when it freezes all other scripts as well, because Lua is not multithreaded. It took this long because of the amount of iterations in the benchmark, and that this ran on my computer.

A roblox server has a lot more power than my computer. However, my computer is likely much stronger than the power given to a single server instance for a roblox game. This will make all calculations take longer for that server instance. That’s why it’s important to optimize everything heavily on the server-side!