diff --git a/bench/index.js b/bench/index.js index 47b5149..dce6e17 100644 --- a/bench/index.js +++ b/bench/index.js @@ -1,62 +1,49 @@ var protobuf = require('../') var fs = require('fs') var path = require('path') +var Benchmark = require('benchmark') var messages = protobuf(fs.readFileSync(path.join(__dirname, 'bench.proto'))) - -var TIMES = 1000000 - -var then = 0 -var diff = 0 - -var run = function (name, encode, decode) { - var EXAMPLE = { - foo: 'hello', - hello: 42, - payload: Buffer.from('a'), - meh: { - b: { - tmp: { - baz: 1000 - } - }, - lol: 'lol' - } +var Test = messages.Test + +var obj = { + foo: 'hello', + hello: 42, + payload: Buffer.from('a'), + meh: { + b: { + tmp: { + baz: 1000 + } + }, + lol: 'lol' } - - var EXAMPLE_BUFFER = encode(EXAMPLE) - var i - - console.log('Benchmarking %s', name) - console.log(' Running object encoding benchmark...') - - then = Date.now() - for (i = 0; i < TIMES; i++) { - encode(EXAMPLE) - } - diff = Date.now() - then - - console.log(' Encoded %d objects in %d ms (%d enc/s)\n', TIMES, diff, (1000 * TIMES / diff).toFixed(0)) - - console.log(' Running object decoding benchmark...') - - then = Date.now() - for (i = 0; i < TIMES; i++) { - decode(EXAMPLE_BUFFER) - } - diff = Date.now() - then - - console.log(' Decoded %d objects in %d ms (%d dec/s)\n', TIMES, diff, (1000 * TIMES / diff).toFixed(0)) - - console.log(' Running object encoding+decoding benchmark...') - - then = Date.now() - for (i = 0; i < TIMES; i++) { - decode(encode(EXAMPLE)) - } - diff = Date.now() - then - - console.log(' Encoded+decoded %d objects in %d ms (%d enc+dec/s)\n', TIMES, diff, (1000 * TIMES / diff).toFixed(0)) } - -run('JSON (baseline)', JSON.stringify, JSON.parse) -run('protocol-buffers', messages.Test.encode, messages.Test.decode) +var json = JSON.stringify(obj) +var buffer = Test.encode(obj) + +var benchOptions = {minSamples: 500} +var suite = new Benchmark.Suite() + +suite + .add('JSON (baseline) encoding:', function () { + JSON.stringify(obj) + }, benchOptions) + .add('JSON (baseline) decoding:', function () { + JSON.parse(json) + }, benchOptions) + .add('JSON (baseline) encoding + decoding:', function () { + JSON.parse(JSON.stringify(obj)) + }, benchOptions) + .add('protocol-buffers encoding:', function () { + Test.encode(obj) + }, benchOptions) + .add('protocol-buffers decoding:', function () { + Test.decode(buffer) + }, benchOptions) + .add('protocol-buffers encoding + decoding:', function () { + Test.decode(Test.encode(obj)) + }, benchOptions) + .on('cycle', function (event) { + console.log(String(event.target)) + }) + .run({async: false}) diff --git a/compile.js b/compile.js index aaadc51..0bf47b7 100644 --- a/compile.js +++ b/compile.js @@ -34,11 +34,12 @@ var defaultValue = function (f, def) { switch (f.type) { case 'string': - return isString(def) ? def : '""' + return isString(def) ? def : 'null' case 'bool': if (def === 'true') return 'true' - return 'false' + if (def === 'false') return 'false' + return 'null' case 'float': case 'double': @@ -52,7 +53,7 @@ var defaultValue = function (f, def) { case 'int32': case 'sint64': case 'sint32': - return '' + Number(def || 0) + return (def === null) ? 'null' : '' + Number(def || 0) default: return 'null' diff --git a/package.json b/package.json index c1c725a..908cd15 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "varint": "^5.0.0" }, "devDependencies": { + "benchmark": "^1.0.0", "standard": "^10.0.3", "tape": "^4.8.0" }, diff --git a/test/defaults.js b/test/defaults.js index 358b887..96ec4b0 100644 --- a/test/defaults.js +++ b/test/defaults.js @@ -18,21 +18,27 @@ tape('defaults decode', function (t) { num: 10, foo1: 2, foo2: 2, - foos: [] + foos: [], + float_value: 4.932, + double_value: 1.2322 }, '1 default') t.same(o1, { num: 42, foo1: 2, foo2: 1, - foos: [] + foos: [], + float_value: 4.932, + double_value: 1.2322 }, 'all defaults') t.same(Defaults.decode(b2), { num: 10, foo1: 2, foo2: 1, - foos: [1] + foos: [1], + float_value: 4.932, + double_value: 1.2322 }, '2 defaults') t.end() diff --git a/test/optional.js b/test/optional.js new file mode 100644 index 0000000..118da92 --- /dev/null +++ b/test/optional.js @@ -0,0 +1,53 @@ +var tape = require('tape') +var protobuf = require('../require') +var Optional = protobuf('./test.proto').Optional + +tape('defaults decode null', function (t) { + var emptyBuffer = Buffer.alloc(0) + var floats = new Float32Array(1) // floats require special handling for equality + floats[0] = 4.3234 + var partialObj = { + 'int32': 12345, + 'float': floats[0], + 'double': 12.49342, + 'string': 'foo' + } + var partialBuffer = Optional.encode(partialObj) + console.log(JSON.stringify(Optional.decode(partialBuffer))) + + t.same(Optional.decode(emptyBuffer), { + 'sint32': null, + 'sint64': null, + 'int32': null, + 'uint32': null, + 'int64': null, + 'float': null, + 'double': null, + 'string': null, + 'bool': null, + 'int32_default': 46, + 'float_default': 4.932, + 'double_default': 1.2322, + 'string_default': 'foo', + 'bool_default': true + }, 'all defaults') + + t.same(Optional.decode(partialBuffer), { + 'sint32': null, + 'sint64': null, + 'int32': 12345, + 'uint32': null, + 'int64': null, + 'float': floats[0], + 'double': 12.49342, + 'string': 'foo', + 'bool': null, + 'int32_default': 46, + 'float_default': 4.932, + 'double_default': 1.2322, + 'string_default': 'foo', + 'bool_default': true + }, 'partial defaults') + + t.end() +}) diff --git a/test/test.proto b/test/test.proto index ff84e90..12e1111 100644 --- a/test/test.proto +++ b/test/test.proto @@ -60,6 +60,8 @@ message Defaults { optional FOO foo1 = 2 [default = B]; optional FOO foo2 = 3; repeated FOO foos = 4; + optional float float_value = 5 [default = 4.932]; + optional double double_value = 6 [default = 1.2322]; } @@ -107,3 +109,21 @@ message ComplexProperty { string string_value = 10; } } + +message Optional { + optional sint32 sint32 = 1; + optional sint64 sint64 = 2; + optional int32 int32 = 3; + optional uint32 uint32 = 4; + optional int64 int64 = 5; + optional float float = 6; + optional double double = 7; + optional string string = 8; + optional bool bool = 9; + + optional int32 int32_default = 10 [default = 46]; + optional float float_default = 11 [default = 4.932]; + optional double double_default = 12 [default = 1.2322]; + optional string string_default = 13 [default = "foo"]; + optional bool bool_default = 14 [default = true]; +}