Comparing version 2.3.0 to 2.4.0
/** Entry point */ | ||
'use strict'; | ||
/* Requires ------------------------------------------------------------------*/ | ||
@@ -11,2 +9,2 @@ | ||
module.exports = { schema }; | ||
module.exports = { schema }; |
{ | ||
"name": "compactr", | ||
"version": "2.3.0", | ||
"version": "2.4.0", | ||
"description": "Schema based serialization made easy", | ||
"main": "index.js", | ||
"scripts": { | ||
"lint": "eslint .", | ||
"lint:fix": "eslint . --fix", | ||
"test": "mocha tests/index.js --exit", | ||
"bench": "node benchmarks/array.js && node benchmarks/boolean.js && node benchmarks/double.js && node benchmarks/integer.js && node benchmarks/object.js && node benchmarks/string.js" | ||
}, | ||
"funding": { | ||
"type": "Github", | ||
"url": "https://github.com/sponsors/fed135" | ||
}, | ||
"repository": { | ||
@@ -15,4 +21,2 @@ "type": "git", | ||
"keywords": [ | ||
"socket", | ||
"io", | ||
"compactr", | ||
@@ -30,2 +34,7 @@ "compact", | ||
], | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "yarn lint" | ||
} | ||
}, | ||
"author": "frederic charette <fredericcharette@gmail.com>", | ||
@@ -39,5 +48,8 @@ "license": "Apache-2.0", | ||
"benchmark": "^2.1.4", | ||
"chai": "^4.1.0", | ||
"mocha": "^5.0.0" | ||
"chai": "^4.2.0", | ||
"eslint": "^6.7.1", | ||
"husky": "^3.1.0", | ||
"mocha": "^6.2.0", | ||
"protobufjs": "^6.8.8" | ||
} | ||
} |
@@ -71,15 +71,4 @@ <h1 align="center"> | ||
## Speed comparison | ||
![Speed](http://res.cloudinary.com/kalm/image/upload/v1507323565/compactr_speed_adhlsk.png) | ||
*Measured against plain JSON serialization + convertion to buffer. Compactr serialization is performed with default settings via the partial (content only) load method* | ||
## Size comparison | ||
![Size](http://res.cloudinary.com/kalm/image/upload/v1507323565/compactr_bytes_cbjxka.png) | ||
JSON: `{"id":123,"name":"John"}`: 24 bytes | ||
@@ -119,3 +108,35 @@ | ||
## Benchmarks | ||
``` | ||
[Array] JSON x 651 ops/sec ±0.91% (92 runs sampled) | ||
[Array] Compactr x 464 ops/sec ±1.49% (87 runs sampled) | ||
[Array] size: { json: 0, compactr: 10 } | ||
[Boolean] JSON x 844 ops/sec ±0.95% (92 runs sampled) | ||
[Boolean] Compactr x 991 ops/sec ±1.36% (82 runs sampled) | ||
[Boolean] Protobuf x 2,940 ops/sec ±1.41% (87 runs sampled) | ||
[Boolean] size: { json: 23, compactr: 5, protobuf: 5 } | ||
[Float] JSON x 560 ops/sec ±1.00% (84 runs sampled) | ||
[Float] Compactr x 823 ops/sec ±1.46% (85 runs sampled) | ||
[Float] Protobuf x 2,433 ops/sec ±2.19% (82 runs sampled) | ||
[Float] size: { json: 41, compactr: 12, protobuf: 12 } | ||
[Integer] JSON x 792 ops/sec ±1.56% (83 runs sampled) | ||
[Integer] Compactr x 736 ops/sec ±1.31% (82 runs sampled) | ||
[Integer] Protobuf x 2,960 ops/sec ±1.41% (90 runs sampled) | ||
[Integer] size: { json: 24, compactr: 12, protobuf: 7 } | ||
[Object] JSON x 370 ops/sec ±1.25% (82 runs sampled) | ||
[Object] Compactr x 308 ops/sec ±0.93% (82 runs sampled) | ||
[Object] Protobuf x 824 ops/sec ±2.45% (86 runs sampled) | ||
[Object] size: { json: 46, compactr: 13, protobuf: 25 } | ||
[String] JSON x 274 ops/sec ±1.96% (79 runs sampled) | ||
[String] Compactr x 400 ops/sec ±0.92% (83 runs sampled) | ||
[String] Protobuf x 716 ops/sec ±0.98% (86 runs sampled) | ||
[String] size: { json: 57, compactr: 14, protobuf: 28 } | ||
``` | ||
## Want to help ? | ||
@@ -128,2 +149,2 @@ | ||
[Apache 2.0](LICENSE) (c) 2017 Frederic Charette | ||
[Apache 2.0](LICENSE) (c) 2019 Frederic Charette |
/** Type Coersion utilities */ | ||
'use asm'; | ||
/* Methods -------------------------------------------------------------------*/ | ||
@@ -62,3 +60,3 @@ | ||
array, | ||
object | ||
}; | ||
object, | ||
}; |
/** Decoding utilities */ | ||
'use asm'; | ||
/* Local variables -----------------------------------------------------------*/ | ||
const pow = Math.pow; | ||
const fromChar = String.fromCharCode; | ||
@@ -18,16 +15,30 @@ | ||
/** @private */ | ||
function number(bytes) { | ||
if (bytes.length === 1) return (!(bytes[0] & 0x80))?bytes[0]:((0xff - bytes[0] + 1) * -1); | ||
if (bytes.length === 2) { | ||
const val = (bytes[0] << 8) | bytes[1]; | ||
return (val & 0x8000) ? val | 0xFFFF0000 : val; | ||
} | ||
return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | (bytes[3]); | ||
function int8(bytes) { | ||
return (!(bytes[0] & 0x80))?bytes[0]:((0xff - bytes[0] + 1) * -1); | ||
} | ||
/** @private */ | ||
function int16(bytes) { | ||
const val = (bytes[0] << 8) | bytes[1]; | ||
return (val & 0x8000) ? val | 0xFFFF0000 : val; | ||
} | ||
/** @private */ | ||
function int32(bytes) { | ||
return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | (bytes[3]) | ||
} | ||
function uint8(bytes) { | ||
return bytes[0]; | ||
} | ||
function uint16(bytes) { | ||
return bytes[0] << 8 | bytes[1]; | ||
} | ||
/** @private */ | ||
function unsigned(bytes) { | ||
if (bytes.length === 1) return bytes[0]; | ||
if (bytes.length === 2) return bytes[0] << 8 | bytes[1]; | ||
return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | (bytes[3]); | ||
if (bytes.length === 1) return uint8(bytes); | ||
if (bytes.length === 2) return uint16(bytes); | ||
return int32(bytes); | ||
} | ||
@@ -39,5 +50,5 @@ | ||
for (let i = 0; i < bytes.length; i += 2) { | ||
res.push(unsigned(bytes.subarray(i, i + 2))); | ||
res.push(unsigned([bytes[i], bytes[i + 1]])); | ||
} | ||
return fromChar.apply(null, res); | ||
return fromChar(...res); | ||
} | ||
@@ -47,7 +58,3 @@ | ||
function char8(bytes) { | ||
let res = []; | ||
for (let i = 0; i < bytes.length; i += 1) { | ||
res.push(unsigned(bytes.subarray(i, i + 1))); | ||
} | ||
return fromChar.apply(null, res); | ||
return fromChar(...bytes); | ||
} | ||
@@ -59,5 +66,5 @@ | ||
for (let i = 0; i < bytes.length; i += 4) { | ||
res.push(unsigned(bytes.subarray(i, i + 4))); | ||
res.push(int32([bytes[i], bytes[i + 1], bytes[i + 2], bytes[i + 3]])); | ||
} | ||
return fromChar.apply(null, res); | ||
return fromChar(...res); | ||
} | ||
@@ -69,5 +76,5 @@ | ||
for (let i = 0; i < bytes.length;) { | ||
const size = unsigned(bytes.subarray(i, i + schema.count)); | ||
const size = unsigned(bytes.slice(i, i + schema.count)); | ||
i = (i + schema.count); | ||
ret.push(schema.transformOut(bytes.subarray(i, i + size))); | ||
ret.push(schema.transformOut(bytes.slice(i, i + size))); | ||
i = (i + size); | ||
@@ -104,3 +111,3 @@ } | ||
} | ||
return (s ? -1 : 1) * m * pow(2, e - 52); | ||
return (s ? -1 : 1) * m * Math.pow(2, e - 52); | ||
} | ||
@@ -113,5 +120,5 @@ | ||
number: double, | ||
int8: number, | ||
int16: number, | ||
int32: number, | ||
int8, | ||
int16, | ||
int32, | ||
double, | ||
@@ -125,5 +132,5 @@ string, | ||
unsigned, | ||
unsigned8: unsigned, | ||
unsigned16: unsigned, | ||
unsigned32: unsigned | ||
unsigned8: uint8, | ||
unsigned16: uint16, | ||
unsigned32: int32, | ||
}; |
/** Encoding utilities */ | ||
'use asm'; | ||
/* Local variables -----------------------------------------------------------*/ | ||
@@ -16,3 +14,2 @@ | ||
const eOut = pow(2, 1022) * bias; | ||
const fastPush = Array.prototype.push; | ||
@@ -59,6 +56,16 @@ /* Methods -------------------------------------------------------------------*/ | ||
/** @private */ | ||
function char8(val) { | ||
const chars = []; | ||
for (let i = 0; i < val.length; i++) { | ||
chars.push(val.charCodeAt(i) % 0xff); | ||
} | ||
return chars; | ||
} | ||
/** @private */ | ||
function string(encoding, val) { | ||
const chars = []; | ||
for (let i = 0; i < val.length; i++) { | ||
fastPush.apply(chars, encoding(val.charCodeAt(i))); | ||
chars.push(...encoding(val.charCodeAt(i))); | ||
} | ||
@@ -74,4 +81,3 @@ | ||
let encoded = schema.transformIn(val[i]); | ||
fastPush.apply(ret, schema.getSize(encoded.length)); | ||
fastPush.apply(ret, encoded); | ||
ret.push(...schema.getSize(encoded.length), ...encoded); | ||
} | ||
@@ -91,13 +97,10 @@ return ret; | ||
function double(val) { | ||
var buffer = []; | ||
var e, m, c; | ||
var mLen = 52; | ||
var nBytes = 8; | ||
var eLen = 11; | ||
var eMax = 2047; | ||
var eBias = 1023; | ||
var rt = 0; | ||
var i = 7; | ||
var d = -1; | ||
var s = val <= 0 ? 1 : 0; | ||
let buffer = []; | ||
let e, m, c; | ||
let eMax = 2047; | ||
let eBias = 1023; | ||
let rt = 0; | ||
let i = 7; | ||
let d = -1; | ||
let s = val <= 0 ? 1 : 0; | ||
val = abs(val); | ||
@@ -163,3 +166,3 @@ e = floor(log(val) / ln2); | ||
string: string.bind(null, unsigned16), | ||
char8: string.bind(null, unsigned8), | ||
char8, | ||
char16: string.bind(null, unsigned16), | ||
@@ -172,3 +175,3 @@ char32: string.bind(null, unsigned32), | ||
unsigned16, | ||
unsigned32 | ||
unsigned32, | ||
}; |
/** Data reader component */ | ||
'use asm'; | ||
/* Requires ------------------------------------------------------------------*/ | ||
@@ -45,3 +43,3 @@ | ||
key, | ||
size: key.size || Decoder.unsigned(bytes.subarray(caret + 1, caret + key.count + 1)) | ||
size: key.size || Decoder.unsigned(bytes.subarray(caret + 1, caret + key.count + 1)), | ||
}; | ||
@@ -48,0 +46,0 @@ return caret + key.count + 1; |
/** Schema parsing component */ | ||
'use asm'; | ||
/* Requires ------------------------------------------------------------------*/ | ||
@@ -37,3 +35,3 @@ | ||
unsigned16: 2, | ||
unsigned32: 4 | ||
unsigned32: 4, | ||
}; | ||
@@ -49,3 +47,3 @@ | ||
contentBegins: 0, | ||
options | ||
options, | ||
}; | ||
@@ -78,3 +76,3 @@ scope.indices = preformat(schema); | ||
count, | ||
nested: childSchema | ||
nested: childSchema, | ||
}; | ||
@@ -91,3 +89,3 @@ }); | ||
key: scope.indices[key], | ||
size: scope.indices[key].size || sizeRef[scope.indices[key].type] | ||
size: scope.indices[key].size || sizeRef[scope.indices[key].type], | ||
}); | ||
@@ -94,0 +92,0 @@ } |
/** Data writer component */ | ||
'use asm'; | ||
/* Local variables -----------------------------------------------------------*/ | ||
const fastPush = Array.prototype.push; | ||
/* Methods -------------------------------------------------------------------*/ | ||
@@ -43,4 +37,3 @@ | ||
function splitBytes(encoded, key) { | ||
scope.headerBytes.push(scope.indices[key].index); | ||
fastPush.apply(scope.headerBytes, scope.indices[key].getSize(encoded.length)); | ||
scope.headerBytes.push(scope.indices[key].index, ...scope.indices[key].getSize(encoded.length)); | ||
let res = encoded; | ||
@@ -58,3 +51,3 @@ if (scope.indices[key].size !== null) { | ||
} | ||
fastPush.apply(scope.contentBytes, res); | ||
scope.contentBytes.push(...res); | ||
} | ||
@@ -91,6 +84,3 @@ | ||
function concat(header, content) { | ||
const res = []; | ||
fastPush.apply(res, header); | ||
fastPush.apply(res, content); | ||
return res; | ||
return [...header, ...content]; | ||
} | ||
@@ -97,0 +87,0 @@ |
Sorry, the diff of this file is not supported yet
148
21722
6
10
573