Created
August 16, 2016 21:31
-
-
Save trevnorris/5ddda4b7bcc628cc81f14e62dc94ad65 to your computer and use it in GitHub Desktop.
Benchmark testing parsing JSON data vs parsing a binary format from a Buffer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const print = process._rawDebug; | |
const ITER = 1e6; | |
const four_nulls = '\u0000\u0000\u0000\u0000'; | |
// Mock object of only strings. | |
const test_obj = { | |
foobarbaz1: Math.random().toString(16).substr(2), | |
foobarbaz2: 'abcdefghijklmnop'.repeat(5), | |
foobarbaz3: 'qrstuvwxyz'.repeat(3), | |
foobarbaz4: 'bamboombing', | |
foobarbaz5: 'flipfloop'.repeat(6), | |
foobarbaz6: 'aslkfdjsalfj'.repeat(4), | |
foobarbaz7: 'nananananananana BATMAN!'.repeat(10), | |
foobarbaz8: 'some crazy crew', | |
}; | |
const test_buf = Buffer(JSON.stringify(test_obj)); | |
const bin_data = genBinData(test_obj); | |
print('byte length:', test_buf.byteLength); | |
//print(new GenObjFromBin(bin_data)); | |
//return; | |
var t = process.hrtime(); | |
for (var i = 0; i < ITER; i++) { | |
// HERE: Comment out one or the other to run the benchmark. | |
//JSON.parse(test_buf); | |
//new GenObjFromBin(bin_data); | |
//JSON.stringify(test_obj); | |
genBinData(test_obj); | |
} | |
printTime(process.hrtime(t)); | |
function printTime(t) { | |
const ns = t[0] * 1e9 + t[1]; | |
print((ns / ITER).toFixed(2) + ' ns/op'); | |
} | |
/* | |
* Structure of the data in the Buffer: | |
* | |
* ┌────────┬─────────────┬────────┬─────────────┬─────┐ | |
* │ uint32 │ string data │ uint32 │ string data │ ... │ | |
* └────────┴─────────────┴────────┴─────────────┴─────┘ | |
* | |
* Each uint32 is binary and must be read using buf.readUInt32LE(), and is the | |
* length of the string data. From this each string can be sliced off. | |
*/ | |
function readFields(buf) { | |
const ret_array = []; | |
const buf_length = buf.length; | |
var offset = 0; | |
do { | |
const string_length = buf.readUInt32LE(offset); | |
ret_array.push(buf.toString('utf8', offset + 4, offset + 4 + string_length)); | |
offset += 4 + string_length; | |
} while (offset < buf_length); | |
return ret_array; | |
} | |
// Constructor used to create the new instance containing all the fields. | |
function GenObjFromBin(bin) { | |
const obj_array = readFields(bin); | |
this.foobarbaz1 = obj_array[0]; | |
this.foobarbaz2 = obj_array[1]; | |
this.foobarbaz3 = obj_array[2]; | |
this.foobarbaz4 = obj_array[3]; | |
this.foobarbaz5 = obj_array[4]; | |
this.foobarbaz6 = obj_array[5]; | |
this.foobarbaz7 = obj_array[6]; | |
this.foobarbaz8 = obj_array[7]; | |
} | |
// Helper function to turn an object into the binary form recognized by | |
// readFields(). This assumes all fields in the structure are strings. | |
function genBinData(obj) { | |
const strings_array = []; | |
for (var item in obj) { | |
strings_array.push(obj[item]); | |
} | |
const b = Buffer(four_nulls + strings_array.join(four_nulls)); | |
const indexes_array = [0]; | |
var last_index = 0; | |
do { | |
const idx = b.indexOf(four_nulls, last_index + 4, 'binary'); | |
if (idx === -1) break; | |
indexes_array.push(idx); | |
last_index = idx; | |
} while(true); | |
for (var i = 0; i < indexes_array.length; i++) { | |
const size = indexes_array.length - 1 === i ? b.length - indexes_array[i] - 4 : indexes_array[i + 1] - indexes_array[i] - 4; | |
b.writeUInt32LE(size, indexes_array[i]); | |
} | |
return b; | |
/* | |
const bufs_array = []; | |
const strings_array = []; | |
const lengths_array = []; | |
var lengths_total = 0; | |
for (var item in obj) { | |
const item_byte_length = Buffer.byteLength(obj[item]); | |
lengths_array.push(item_byte_length); | |
lengths_total += item_byte_length; | |
strings_array.push(obj[item]); | |
//const byte_length = Buffer.byteLength(obj[item]); | |
//const b = Buffer(byte_length + 4); | |
//b.writeUInt32LE(byte_length); | |
//b.write(obj[item], 4); | |
//bufs_array.push(b); | |
} | |
//return Buffer.concat(bufs_array); | |
const b = Buffer(lengths_total + lengths_array.length * 4); | |
var offset = 0; | |
var idx = 0; | |
const write_string = ' ' + strings_array.join(' '); | |
b.write(write_string); | |
for (var i = 0; i < lengths_array.length; i++) { | |
b.writeUInt32LE(lengths_array[i], offset); | |
offset += lengths_array[i] + 4; | |
} | |
return b; | |
*/ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment