I’m trying to use protobuf to accelerate data transfers between my front and back.
As a POC, I tried to load a JSON file, turn it into a protobuf buffer, and save the result in a new file.
But it turns out that the new file is heavier than the JSON one. Did I do something wrong?
Here are my files:
// input.proto
syntax = "proto3";
message MyData {
repeated float a = 1;
repeated float b = 2;
repeated float c = 3;
float d = 4;
repeated float e = 5;
}
// index.mjs
import protobuf from 'protobufjs';
import fs from 'fs';
protobuf.load('./input.proto', (err, root) => {
const payload = JSON.parse(fs.readFileSync('./input.json', {encoding: 'utf8'}));
var Message = root.lookupType("MyData");
var errMsg = Message.verify(payload);
if (errMsg)
throw Error(errMsg);
var message = Message.create(payload);
const buffer = Message.encode(message).finish();
fs.writeFileSync('./output.pb', buffer, 'binary');
}, () => {
});
// input.json
{
"a": [1, 2.4, 3, 4],
"b": [1, 2, 3, 4],
"c": [1, 2, 3.2, 4],
"d": 10.321,
"e": [1, 2, 3.7, 4],
}
(my actual json is much bigger than that, but it respects the same format as this one)
And finally :
$ du -h input.json output.pb
2,0M input.json
2,5M output.pb
Thanks for your help!
2
Answers
I ended up using NodeJS Buffers to reduce the size of my floats, here's my solution :
On reason could be that
float
in Protocol Buffers is encoded as I32, so every number needs 4 bytes. In JSON (UTF8) a single digit number is represented in 3 bytes (space, number and comma). You can also omit the space, making JSON even more compact.