Skip to content

Use native JSON instead of MessagePack is faster #103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from

Conversation

buinskii
Copy link

Test source:

var msgpackLite = require('msgpack-lite');
var msgpackJs = require('msgpack-js');
var Benchmark = require('benchmark');
var msgpack = require('msgpack');
var fs = require('fs');
var _ = require('lodash');

var testData = {
    blablabla: {
        hello: 'World',
        country: 255
    },
    x: 0,
    y: 253745
};

var suite = new Benchmark.Suite;
suite.add('MessagePack encode/decode', function() {
        var encoded = msgpack.pack(testData);
        var decoded = msgpack.unpack(encoded);
    })
    .add('MessagePackLite encode/decode', function() {
        var encoded = msgpackLite.encode(testData);
        var decoded = msgpackLite.decode(encoded);
    })
    .add('MessagePackJS encode/decode', function() {
        var encoded = msgpackJs.encode(testData);
        var decoded = msgpackJs.decode(encoded);
    })
    .add('JSON encode/decode', function() {
        var encoded = JSON.stringify(testData);
        var decoded = JSON.parse(encoded);
    })
    .on('cycle', function(event) {
        console.log(String(event.target));
    })
    .on('complete', function() {
        console.log('Fastest is ' + this.filter('fastest').map('name'));
    })
    .run({ 'async': false });

Test results:

MessagePack encode/decode x 70,190 ops/sec ±2.38% (87 runs sampled)
MessagePackLite encode/decode x 75,994 ops/sec ±2.36% (86 runs sampled)
MessagePackJS encode/decode x 34,879 ops/sec ±2.74% (90 runs sampled)
JSON encode/decode x 371,367 ops/sec ±1.71% (91 runs sampled)
Fastest is JSON encode/decode

@didaxRedux
Copy link

didaxRedux commented May 6, 2016

The msgpack library is used to compress data, so fast encode/decode is balanced by bandwidth saves.
Could you test average weight of each message during benchmark? It could be interesting...

@buinskii
Copy link
Author

buinskii commented May 6, 2016

Thanks for reply! I modified my test:

var msgpackLite = require('msgpack-lite');
var msgpackJs = require('msgpack-js');
var Benchmark = require('benchmark');
var msgpack = require('msgpack');
var fs = require('fs');
var _ = require('lodash');
var request = require('request');

var testData = {
    blablabla: {
        hello: 'World',
        country: 255
    },
    x: 0,
    y: 253745
};

function test(title, testData, callback) {
    console.log('---', title, '---');
    console.log('| JSON.stringify() result size in bytes:    ' , new Buffer(JSON.stringify(testData)).byteLength);
    console.log('| MessagePack.pack() result size in bytes:  ' , msgpack.pack(testData).byteLength);
    console.log('| msgpackLite.encode() result size in bytes:' , msgpackLite.encode(testData).byteLength);
    console.log('| msgpackJs.encode() result size in bytes:  ' , msgpackJs.encode(testData).byteLength);
    console.log('| ');
    var suite = new Benchmark.Suite;
    suite.add('JSON encode/decode', function() {
            var encoded = JSON.stringify(testData);
            var decoded = JSON.parse(encoded);
        })
        .add('MessagePack encode/decode', function() {
            var encoded = msgpack.pack(testData);
            var decoded = msgpack.unpack(encoded);
        })
        .add('MessagePackLite encode/decode', function() {
            var encoded = msgpackLite.encode(testData);
            var decoded = msgpackLite.decode(encoded);
        })
        .add('MessagePackJS encode/decode', function() {
            var encoded = msgpackJs.encode(testData);
            var decoded = msgpackJs.decode(encoded);
        })
        .on('cycle', function(event) {
            console.log('| ', String(event.target));
        })
        .on('complete', function() {
            console.log('| ');
            console.log('| Fastest is ' + this.filter('fastest').map('name'));
            console.log('---');
            callback();
        })
        .run({ 'async': false });
}

test('small data', testData, function() {

    request.get('http://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demo', function(err, response, body) {
        test('large data', JSON.parse(body), function() {});
    });

});
--- small data ---
| JSON.stringify() result size in bytes:     62
| MessagePack.pack() result size in bytes:   44
| msgpackLite.encode() result size in bytes: 44
| msgpackJs.encode() result size in bytes:   44
| 
|  JSON encode/decode x 370,038 ops/sec ±0.60% (90 runs sampled)
|  MessagePack encode/decode x 78,072 ops/sec ±1.56% (87 runs sampled)
|  MessagePackLite encode/decode x 88,616 ops/sec ±1.86% (80 runs sampled)
|  MessagePackJS encode/decode x 40,436 ops/sec ±2.23% (88 runs sampled)
| 
| Fastest is JSON encode/decode
---
--- large data ---
| JSON.stringify() result size in bytes:     2887
| MessagePack.pack() result size in bytes:   2304
| msgpackLite.encode() result size in bytes: 2304
| msgpackJs.encode() result size in bytes:   2306
| 
|  JSON encode/decode x 27,167 ops/sec ±1.51% (90 runs sampled)
|  MessagePack encode/decode x 5,480 ops/sec ±3.56% (82 runs sampled)
|  MessagePackLite encode/decode x 5,565 ops/sec ±1.83% (84 runs sampled)
|  MessagePackJS encode/decode x 1,358 ops/sec ±1.65% (86 runs sampled)
| 
| Fastest is JSON encode/decode
---

What about use msgpack-lite library instead of msgpack-js ? msgpack-lite is 2x faster

@didaxRedux
Copy link

Yes... you are right!
I have only a doubt about UInt64 support (see #105) but your analysis is clear.

@darrachequesne
Copy link
Member

Hi! I think a PR had already been opened on this matter: #44. Unfortunately, as pointed out by @rauchg:

JSON doesn't support binary data.

Note: maybe we should add a test for this 👼

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants