-
Notifications
You must be signed in to change notification settings - Fork 4
JBB Performance
In the javascript world there quite few binary encoding projects. The most widespread ones are the Binary-JSON (BSON) and MessagePack file formats. Even though they are not directly targeting Javascript applications, they are available as npm
modules for both node.js and the browser.
For this performance tests we tested these technologies for a variety of data sets. It was surprising to see that JBB outperformed the other two both in file size and loading speed.
The encoding time of JBB is slower because of the way the bundles are created: Each one of it's four data streams are written into 4 individual files and then merged into the final bundle. In addition, JBB is not a streaming format, requiring some additional time to compile it's internal lookup tables.
For this performance tests we compared the following various binary encoders available on npm
for javascript applications:
For the following data:
- Low-resolution Country Polygons (GeoJSON) (251K)
- High-resolution Country Polygons (GeoJSON) (673K)
- Randomly generated JSON, mostly with strings (961K)
- 50,000 times repeated instance of
{ 'abcdef' : 1, 'qqq' : 13, '19' : [1, 2, 3, 4] }
(1.8M) - 50,000 times repeated instance of
{ 'abcdef' : Math.random(), 'qqq' : 13, '19' : [Math.random(), Math.random(), Math.random(), Math.random()] }
(5.9M)
We compared the output file size and and loading time. The results are the following:
Data | JSON | BSON | MsgPack | JBB | ||||
---|---|---|---|---|---|---|---|---|
Encode | Decode | Encode | Decode | Encode | Decode | Encode | Decode | |
1 | 5.784ms | 4.428ms | 33.713ms | 32.986ms | 6.021ms | 8.770ms | 127.750ms | 7.962ms |
2 | 8.444ms | 13.871ms | 41.690ms | 48.039ms | 14.350ms | 18.508ms | 215.315ms | 18.269ms |
3 | 5.110ms | 13.339ms | 33.584ms | 30.697ms | 18.537ms | 16.346ms | 186.009ms | 18.545ms |
4 | 59.316ms | 84.020ms | 237.391ms | 404.492ms | 151.971ms | 153.366ms | 294.919ms | 5.308ms |
5 | 117.916ms | 111.693ms | 304.340ms | 368.778ms | 168.251ms | 186.816ms | 539.299ms | 79.913ms |
We also tested how well the file gets compressed, since GZip compression can be transparently applied on HTTP data. Each file was compressed at maximum GZip compression (-9
).
Data | JSON | BSON | MsgPack | JBB | ||||
---|---|---|---|---|---|---|---|---|
Raw | GZip | Raw | GZip | Raw | GZip | Raw | GZip | |
1 | 251K | 101K | 349K | 172K | 214K | 146K | 110K | 70K |
2 | 588K | 204K | 534K | 207K | 361K | 184K | 157K | 78K |
3 | 752K | 210K | 801K | 238K | 667K | 220K | 523K | 166K |
4 | 1,806K | 5.4K | 3,407K | 129K | 977K | 2.5K | 104B | 118B |
5 | 6,023K | 2,290K | 4,384K | 1,575K | 2,930K | 1,360K | 1,074K | 877K |
- JBB is about 70% faster than Binary-JSON (BSON) and about 30% faster than MsgPack on decoding speed, even with one negative test-case (#3).
- JBB creates files that (even their compressed versions) are about 61% smaller than Binary-JSON (BSON) and about 55% smaller than MsgPack.
The following code snippets were used to measure the numbers above:
For loading the sample JSON files:
var fs = require('fs');
var _data = JSON.parse(fs.readFileSync('data.json', 'utf8'));
For generating dataset 4:
var _data = [];
for (var i=0; i<50000; i++) {
_data.push(
{ 'abcdef' : 1, 'qqq' : 13, '19' : [1, 2, 3, 4] }
);
}
For generating dataset 5:
var _data = [];
for (var i=0; i<50000; i++) {
_data.push(
{ 'abcdef' : Math.random(), 'qqq' : 13, '19' : [Math.random(),Math.random(),Math.random(),Math.random()] }
);
}
For JSON:
// Write down JSON
console.time('Write JSON');
fs.writeFileSync('test-data.json', JSON.stringify(_data))
console.timeEnd('Write JSON');
// Read json
console.time('Read JSON');
_saved = JSON.parse(fs.readFileSync('test-data.json'));
console.timeEnd('Read JSON');
For BSON:
var bson = require("bson");
var BSON = new bson.BSONPure.BSON();
// Write down BSON
console.time('Write BSON');
fs.writeFileSync('test-data.bson', BSON.serialize(_data, false, true, false) );
console.timeEnd('Write BSON');
// Read BSON
console.time('Read BSON');
_saved = BSON.deserialize(fs.readFileSync('test-data.bson'));
console.timeEnd('Read BSON');
For MsgPack:
var msgpack = require('msgpack');
// Write down MSGPACK
console.time('Write MsgPack');
fs.writeFileSync('test-data.msgpack', msgpack.pack(_data) );
console.timeEnd('Write MsgPack');
// Read MSGPACK
console.time('Read MsgPack');
_saved = msgpack.unpack(fs.readFileSync('test-data.msgpack'));
console.timeEnd('Read MsgPack');
For JBB:
var JBBEncoder = require('jbb/encoder');
var JBBDecoder = require('jbb/decoder');
// Write down JBB
console.time('Write JBB');
var bundle = new JBBEncoder("test-data.jbb");
bundle.encode( _data, 'countries' );
bundle.close();
console.timeEnd('Write JBB');
// Read JBB
console.time('Read JBB');
var bundle = new JBBDecoder("./");
bundle.add('test-data.jbb');
bundle.load(function(err, db) {
console.timeEnd('Read JBB');
});