msgpackr 1.5.1 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/index.js +61 -4
- package/dist/index.min.js +52 -51
- package/dist/node.cjs +61 -4
- package/dist/test.js +13 -2
- package/pack.js +32 -3
- package/package.json +7 -1
- package/unpack.d.ts +2 -0
- package/unpack.js +29 -1
- package/.vscode/launch.json +0 -23
- package/tests/benchmark-stream.cjs +0 -282
- package/tests/benchmark.cjs +0 -199
- package/tests/example.json +0 -52
- package/tests/example2.json +0 -26
- package/tests/example3.json +0 -22
- package/tests/example4.json +0 -1
- package/tests/example5.json +0 -12
- package/tests/floats.json +0 -1
- package/tests/index.html +0 -28
- package/tests/sample-large.json +0 -231
- package/tests/strings2.json +0 -1
- package/tests/test-compatibility.cjs +0 -64
- package/tests/test-incomplete.js +0 -41
- package/tests/test-node-iterators.js +0 -72
- package/tests/test-node-stream.js +0 -76
- package/tests/test.js +0 -652
package/dist/test.js
CHANGED
|
@@ -684,6 +684,14 @@
|
|
|
684
684
|
var deserialized = packr.unpack(serialized);
|
|
685
685
|
assert.deepEqual(deserialized, data);
|
|
686
686
|
});
|
|
687
|
+
test('pack/unpack sample data with bundled strings', function(){
|
|
688
|
+
var data = sampleData;
|
|
689
|
+
let structures = [];
|
|
690
|
+
let packr = new Packr({ structures, bundleStrings: true });
|
|
691
|
+
var serialized = packr.pack(data);
|
|
692
|
+
var deserialized = packr.unpack(serialized);
|
|
693
|
+
assert.deepEqual(deserialized, data);
|
|
694
|
+
});
|
|
687
695
|
if (typeof Buffer != 'undefined')
|
|
688
696
|
test('replace data', function(){
|
|
689
697
|
var data1 = {
|
|
@@ -1010,16 +1018,19 @@
|
|
|
1010
1018
|
var data = {
|
|
1011
1019
|
map: map,
|
|
1012
1020
|
date: new Date(1532219539011),
|
|
1021
|
+
invalidDate: new Date('invalid')
|
|
1013
1022
|
};
|
|
1014
1023
|
let packr = new Packr({
|
|
1015
1024
|
mapsAsObjects: true,
|
|
1016
1025
|
useTimestamp32: true,
|
|
1026
|
+
onInvalidDate: () => 'Custom invalid date'
|
|
1017
1027
|
});
|
|
1018
1028
|
var serialized = packr.pack(data);
|
|
1019
1029
|
var deserialized = packr.unpack(serialized);
|
|
1020
1030
|
assert.equal(deserialized.map[4], 'four');
|
|
1021
1031
|
assert.equal(deserialized.map.three, 3);
|
|
1022
1032
|
assert.equal(deserialized.date.getTime(), 1532219539000);
|
|
1033
|
+
assert.equal(deserialized.invalidDate, 'Custom invalid date');
|
|
1023
1034
|
});
|
|
1024
1035
|
test('key caching', function() {
|
|
1025
1036
|
var data = {
|
|
@@ -1199,7 +1210,7 @@
|
|
|
1199
1210
|
let structures = [];
|
|
1200
1211
|
var serialized = pack(data);
|
|
1201
1212
|
console.log('MessagePack size', serialized.length);
|
|
1202
|
-
let packr = new Packr({ structures });
|
|
1213
|
+
let packr = new Packr({ structures, bundleStrings: false });
|
|
1203
1214
|
var serialized = packr.pack(data);
|
|
1204
1215
|
console.log('msgpackr w/ record ext size', serialized.length);
|
|
1205
1216
|
for (var i = 0; i < ITERATIONS; i++) {
|
|
@@ -1210,7 +1221,7 @@
|
|
|
1210
1221
|
var data = sampleData;
|
|
1211
1222
|
this.timeout(10000);
|
|
1212
1223
|
let structures = [];
|
|
1213
|
-
let packr = new Packr({ structures });
|
|
1224
|
+
let packr = new Packr({ structures, bundleStrings: false });
|
|
1214
1225
|
let buffer = typeof Buffer != 'undefined' ? Buffer.alloc(0x10000) : new Uint8Array(0x10000);
|
|
1215
1226
|
|
|
1216
1227
|
for (var i = 0; i < ITERATIONS; i++) {
|
package/pack.js
CHANGED
|
@@ -13,6 +13,8 @@ let target
|
|
|
13
13
|
let targetView
|
|
14
14
|
let position = 0
|
|
15
15
|
let safeEnd
|
|
16
|
+
let bundledStrings = null
|
|
17
|
+
const hasNonLatin = /[\u0080-\uFFFF]/
|
|
16
18
|
const RECORD_SYMBOL = Symbol('record-id')
|
|
17
19
|
export class Packr extends Unpackr {
|
|
18
20
|
constructor(options) {
|
|
@@ -75,6 +77,14 @@ export class Packr extends Unpackr {
|
|
|
75
77
|
position = (position + 7) & 0x7ffffff8 // Word align to make any future copying of this buffer faster
|
|
76
78
|
start = position
|
|
77
79
|
referenceMap = packr.structuredClone ? new Map() : null
|
|
80
|
+
if (packr.bundleStrings) {
|
|
81
|
+
bundledStrings = ['', '']
|
|
82
|
+
target[position++] = 0xd6
|
|
83
|
+
target[position++] = 0x62 // 'b'
|
|
84
|
+
bundledStrings.position = position - start
|
|
85
|
+
position += 4
|
|
86
|
+
} else
|
|
87
|
+
bundledStrings = null
|
|
78
88
|
sharedStructures = packr.structures
|
|
79
89
|
if (sharedStructures) {
|
|
80
90
|
if (sharedStructures.uninitialized)
|
|
@@ -113,6 +123,13 @@ export class Packr extends Unpackr {
|
|
|
113
123
|
structures = sharedStructures || []
|
|
114
124
|
try {
|
|
115
125
|
pack(value)
|
|
126
|
+
if (bundledStrings) {
|
|
127
|
+
targetView.setUint32(bundledStrings.position + start, position - bundledStrings.position - start)
|
|
128
|
+
let writeStrings = bundledStrings
|
|
129
|
+
bundledStrings = null
|
|
130
|
+
pack(writeStrings[0])
|
|
131
|
+
pack(writeStrings[1])
|
|
132
|
+
}
|
|
116
133
|
packr.offset = position // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
|
|
117
134
|
if (referenceMap && referenceMap.idsToInsert) {
|
|
118
135
|
position += referenceMap.idsToInsert.length * 6
|
|
@@ -123,7 +140,7 @@ export class Packr extends Unpackr {
|
|
|
123
140
|
referenceMap = null
|
|
124
141
|
return serialized
|
|
125
142
|
}
|
|
126
|
-
if (encodeOptions
|
|
143
|
+
if (encodeOptions & REUSE_BUFFER_MODE) {
|
|
127
144
|
target.start = start
|
|
128
145
|
target.end = position
|
|
129
146
|
return target
|
|
@@ -162,6 +179,8 @@ export class Packr extends Unpackr {
|
|
|
162
179
|
return returnBuffer
|
|
163
180
|
}
|
|
164
181
|
}
|
|
182
|
+
if (encodeOptions & RESET_BUFFER_MODE)
|
|
183
|
+
position = start
|
|
165
184
|
}
|
|
166
185
|
}
|
|
167
186
|
const pack = (value) => {
|
|
@@ -172,6 +191,13 @@ export class Packr extends Unpackr {
|
|
|
172
191
|
var length
|
|
173
192
|
if (type === 'string') {
|
|
174
193
|
let strLength = value.length
|
|
194
|
+
if (bundledStrings && strLength >= 8 && strLength < 0x1000) {
|
|
195
|
+
let twoByte = hasNonLatin.test(value)
|
|
196
|
+
bundledStrings[twoByte ? 0 : 1] += value
|
|
197
|
+
target[position++] = 0xc1
|
|
198
|
+
pack(twoByte ? -strLength : strLength);
|
|
199
|
+
return
|
|
200
|
+
}
|
|
175
201
|
let headerSize
|
|
176
202
|
// first we estimate the header size, so we can write to the correct location
|
|
177
203
|
if (strLength < 0x20) {
|
|
@@ -638,8 +664,10 @@ extensions = [{
|
|
|
638
664
|
targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0))
|
|
639
665
|
targetView.setUint32(position + 4, seconds)
|
|
640
666
|
} else if (isNaN(seconds)) {
|
|
641
|
-
if (this.onInvalidDate)
|
|
667
|
+
if (this.onInvalidDate) {
|
|
668
|
+
allocateForWrite(0)
|
|
642
669
|
return pack(this.onInvalidDate())
|
|
670
|
+
}
|
|
643
671
|
// Intentionally invalid timestamp
|
|
644
672
|
let { target, targetView, position} = allocateForWrite(3)
|
|
645
673
|
target[position++] = 0xd4
|
|
@@ -832,4 +860,5 @@ export const Encoder = Packr
|
|
|
832
860
|
export { FLOAT32_OPTIONS } from './unpack.js'
|
|
833
861
|
import { FLOAT32_OPTIONS } from './unpack.js'
|
|
834
862
|
export const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS
|
|
835
|
-
export const REUSE_BUFFER_MODE =
|
|
863
|
+
export const REUSE_BUFFER_MODE = 512
|
|
864
|
+
export const RESET_BUFFER_MODE = 1024
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "msgpackr",
|
|
3
3
|
"author": "Kris Zyp",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.2",
|
|
5
5
|
"description": "Ultra-fast MessagePack implementation with extensions for records and structured cloning",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"types": "./index.d.ts",
|
|
@@ -49,6 +49,12 @@
|
|
|
49
49
|
"default": "./unpack.js"
|
|
50
50
|
}
|
|
51
51
|
},
|
|
52
|
+
"files": [
|
|
53
|
+
"/dist",
|
|
54
|
+
"*.md",
|
|
55
|
+
"/*.js",
|
|
56
|
+
"/*.ts"
|
|
57
|
+
],
|
|
52
58
|
"optionalDependencies": {
|
|
53
59
|
"msgpackr-extract": "^1.0.14"
|
|
54
60
|
},
|
package/unpack.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export interface Options {
|
|
|
13
13
|
mapsAsObjects?: boolean
|
|
14
14
|
variableMapSize?: boolean
|
|
15
15
|
copyBuffers?: boolean
|
|
16
|
+
bundleStrings?: boolean
|
|
16
17
|
useTimestamp32?: boolean
|
|
17
18
|
largeBigIntToFloat?: boolean
|
|
18
19
|
encodeUndefinedAsNil?: boolean
|
|
@@ -21,6 +22,7 @@ export interface Options {
|
|
|
21
22
|
shouldShareStructure?: (keys: string[]) => boolean
|
|
22
23
|
getStructures?(): {}[]
|
|
23
24
|
saveStructures?(structures: {}[]): boolean | void
|
|
25
|
+
onInvalidDate?: () => any
|
|
24
26
|
}
|
|
25
27
|
interface Extension {
|
|
26
28
|
Class: Function
|
package/unpack.js
CHANGED
|
@@ -15,6 +15,7 @@ var currentStructures
|
|
|
15
15
|
var srcString
|
|
16
16
|
var srcStringStart = 0
|
|
17
17
|
var srcStringEnd = 0
|
|
18
|
+
var bundledStrings
|
|
18
19
|
var referenceMap
|
|
19
20
|
var currentExtensions = []
|
|
20
21
|
var dataView
|
|
@@ -55,6 +56,7 @@ export class Unpackr {
|
|
|
55
56
|
srcStringEnd = 0
|
|
56
57
|
srcString = null
|
|
57
58
|
strings = EMPTY_ARRAY
|
|
59
|
+
bundledStrings = null
|
|
58
60
|
src = source
|
|
59
61
|
// this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
|
|
60
62
|
// technique for getting data from a database where it can be copied into an existing buffer instead of creating
|
|
@@ -248,7 +250,15 @@ export function read() {
|
|
|
248
250
|
let value
|
|
249
251
|
switch (token) {
|
|
250
252
|
case 0xc0: return null
|
|
251
|
-
case 0xc1:
|
|
253
|
+
case 0xc1:
|
|
254
|
+
if (bundledStrings) {
|
|
255
|
+
value = read() // followed by the length of the string in characters (not bytes!)
|
|
256
|
+
if (value > 0)
|
|
257
|
+
return bundledStrings[1].slice(bundledStrings.position1, bundledStrings.position1 += value)
|
|
258
|
+
else
|
|
259
|
+
return bundledStrings[0].slice(bundledStrings.position0, bundledStrings.position0 -= value)
|
|
260
|
+
}
|
|
261
|
+
return C1; // "never-used", return special object to denote that
|
|
252
262
|
case 0xc2: return false
|
|
253
263
|
case 0xc3: return true
|
|
254
264
|
case 0xc4:
|
|
@@ -898,6 +908,22 @@ currentExtensions[0x78] = () => {
|
|
|
898
908
|
return new RegExp(data[0], data[1])
|
|
899
909
|
}
|
|
900
910
|
|
|
911
|
+
currentExtensions[0x62] = (data) => {
|
|
912
|
+
let dataSize = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]
|
|
913
|
+
let dataPosition = position
|
|
914
|
+
position += dataSize - 4
|
|
915
|
+
bundledStrings = [read(), read()]
|
|
916
|
+
bundledStrings.position0 = 0
|
|
917
|
+
bundledStrings.position1 = 0
|
|
918
|
+
let postBundlePosition = position
|
|
919
|
+
position = dataPosition
|
|
920
|
+
try {
|
|
921
|
+
return read()
|
|
922
|
+
} finally {
|
|
923
|
+
position = postBundlePosition
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
|
|
901
927
|
currentExtensions[0xff] = (data) => {
|
|
902
928
|
// 32-bit date extension
|
|
903
929
|
if (data.length == 4)
|
|
@@ -925,6 +951,7 @@ function saveState(callback) {
|
|
|
925
951
|
let savedSrcString = srcString
|
|
926
952
|
let savedStrings = strings
|
|
927
953
|
let savedReferenceMap = referenceMap
|
|
954
|
+
let savedBundledStrings = bundledStrings
|
|
928
955
|
|
|
929
956
|
// TODO: We may need to revisit this if we do more external calls to user code (since it could be slow)
|
|
930
957
|
let savedSrc = new Uint8Array(src.slice(0, srcEnd)) // we copy the data in case it changes while external data is processed
|
|
@@ -941,6 +968,7 @@ function saveState(callback) {
|
|
|
941
968
|
srcString = savedSrcString
|
|
942
969
|
strings = savedStrings
|
|
943
970
|
referenceMap = savedReferenceMap
|
|
971
|
+
bundledStrings = savedBundledStrings
|
|
944
972
|
src = savedSrc
|
|
945
973
|
sequentialMode = savedSequentialMode
|
|
946
974
|
currentStructures = savedStructures
|
package/.vscode/launch.json
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
// Use IntelliSense to learn about possible attributes.
|
|
3
|
-
// Hover to view descriptions of existing attributes.
|
|
4
|
-
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
-
"version": "0.2.0",
|
|
6
|
-
"configurations": [
|
|
7
|
-
{
|
|
8
|
-
"type": "pwa-node",
|
|
9
|
-
"request": "launch",
|
|
10
|
-
"name": "Run msgpackr tests",
|
|
11
|
-
"runtimeArgs": [
|
|
12
|
-
"test"
|
|
13
|
-
],
|
|
14
|
-
"runtimeExecutable": "npm",
|
|
15
|
-
"skipFiles": [
|
|
16
|
-
"<node_internals>/**"
|
|
17
|
-
],
|
|
18
|
-
"type": "pwa-node",
|
|
19
|
-
"console": "internalConsole",
|
|
20
|
-
"outputCapture": "std"
|
|
21
|
-
}
|
|
22
|
-
]
|
|
23
|
-
}
|
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
var PassThrough = require("stream").PassThrough;
|
|
4
|
-
var async = require("async");
|
|
5
|
-
|
|
6
|
-
let { PackrStream, UnpackrStream } = require("..");
|
|
7
|
-
var msgpack = require("msgpack-lite");
|
|
8
|
-
var Encoder = require("msgpack-lite/lib/encoder").Encoder;
|
|
9
|
-
var Decoder = require("msgpack-lite/lib/decoder").Decoder;
|
|
10
|
-
var notepack = require("notepack");
|
|
11
|
-
|
|
12
|
-
var pkg = require("../package.json");
|
|
13
|
-
|
|
14
|
-
// a sample fluentd message
|
|
15
|
-
var data = ["tag", [[1440949922, {"message": "hi there"}]]];
|
|
16
|
-
var packed = msgpack.encode(data); // 30 bytes per message
|
|
17
|
-
var packsize = packed.length;
|
|
18
|
-
var opcount = 1000000;
|
|
19
|
-
var joincount = 100;
|
|
20
|
-
var packjoin = repeatbuf(packed, joincount); // 3KB per chunk
|
|
21
|
-
var limit = 2;
|
|
22
|
-
|
|
23
|
-
var blocksToJoin = []
|
|
24
|
-
var streamForJoin = new PackrStream();
|
|
25
|
-
streamForJoin.on("data", data => blocksToJoin.push(data));
|
|
26
|
-
for (var j = 0; j < joincount; j++) {
|
|
27
|
-
streamForJoin.write(data);
|
|
28
|
-
}
|
|
29
|
-
var packjoinWithRecords = Buffer.concat(blocksToJoin)
|
|
30
|
-
|
|
31
|
-
var argv = Array.prototype.slice.call(process.argv, 2);
|
|
32
|
-
|
|
33
|
-
if (argv[0] === "-v") {
|
|
34
|
-
console.warn(pkg.name + " " + pkg.version);
|
|
35
|
-
process.exit(0);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (argv[0] - 0) limit = argv.shift() - 0;
|
|
39
|
-
|
|
40
|
-
var list = [
|
|
41
|
-
['new PackrStream().write(obj);', encode5],
|
|
42
|
-
['new UnpackrStream().write(buf);', decode5],
|
|
43
|
-
['stream.write(msgpack.encode(obj));', encode1],
|
|
44
|
-
['stream.write(msgpack.decode(buf));', decode1],
|
|
45
|
-
['stream.write(notepack.encode(obj));', encode4],
|
|
46
|
-
['stream.write(notepack.decode(buf));', decode4],
|
|
47
|
-
['msgpack.Encoder().on("data",ondata).encode(obj);', encode2],
|
|
48
|
-
['msgpack.createDecodeStream().write(buf);', decode3],
|
|
49
|
-
['msgpack.createEncodeStream().write(obj);', encode3],
|
|
50
|
-
['msgpack.Decoder().on("data",ondata).decode(buf);', decode2],
|
|
51
|
-
// ['stream.write(Buffer.from(JSON.stringify(obj)));', stringify],
|
|
52
|
-
// ['stream.write(JSON.parse(buf));', parse]
|
|
53
|
-
];
|
|
54
|
-
|
|
55
|
-
function encode5(callback) {
|
|
56
|
-
var stream = new PackrStream();
|
|
57
|
-
var cnt = counter(callback);
|
|
58
|
-
stream.on("data", cnt.inc);
|
|
59
|
-
stream.on("end", cnt.end);
|
|
60
|
-
for (var j = 0; j < opcount; j++) {
|
|
61
|
-
stream.write(data);
|
|
62
|
-
}
|
|
63
|
-
stream.end();
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function encode1(callback) {
|
|
67
|
-
var stream = new PassThrough();
|
|
68
|
-
var cnt = counter(callback);
|
|
69
|
-
stream.on("data", cnt.buf);
|
|
70
|
-
stream.on("end", cnt.end);
|
|
71
|
-
for (var j = 0; j < opcount; j++) {
|
|
72
|
-
stream.write(msgpack.encode(data));
|
|
73
|
-
}
|
|
74
|
-
stream.end();
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function encode2(callback) {
|
|
78
|
-
var stream = new PassThrough();
|
|
79
|
-
var cnt = counter(callback);
|
|
80
|
-
stream.on("data", cnt.buf);
|
|
81
|
-
stream.on("end", cnt.end);
|
|
82
|
-
var encoder = Encoder();
|
|
83
|
-
encoder.on("data", function(chunk) {
|
|
84
|
-
stream.write(chunk);
|
|
85
|
-
});
|
|
86
|
-
encoder.on("end", function() {
|
|
87
|
-
stream.end();
|
|
88
|
-
});
|
|
89
|
-
for (var j = 0; j < opcount; j++) {
|
|
90
|
-
encoder.encode(data);
|
|
91
|
-
}
|
|
92
|
-
encoder.end();
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function encode3(callback) {
|
|
96
|
-
var stream = msgpack.createEncodeStream();
|
|
97
|
-
var cnt = counter(callback);
|
|
98
|
-
stream.on("data", cnt.buf);
|
|
99
|
-
stream.on("end", cnt.end);
|
|
100
|
-
for (var j = 0; j < opcount; j++) {
|
|
101
|
-
stream.write(data);
|
|
102
|
-
}
|
|
103
|
-
stream.end();
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function encode4(callback) {
|
|
107
|
-
var stream = new PassThrough();
|
|
108
|
-
var cnt = counter(callback);
|
|
109
|
-
stream.on("data", cnt.buf);
|
|
110
|
-
stream.on("end", cnt.end);
|
|
111
|
-
for (var j = 0; j < opcount; j++) {
|
|
112
|
-
stream.write(notepack.encode(data));
|
|
113
|
-
}
|
|
114
|
-
stream.end();
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function decode5(callback) {
|
|
118
|
-
var stream = new UnpackrStream();
|
|
119
|
-
var cnt = counter(callback);
|
|
120
|
-
stream.on("data", cnt.inc);
|
|
121
|
-
stream.on("end", cnt.end);
|
|
122
|
-
for (var j = 0; j < opcount / joincount; j++) {
|
|
123
|
-
stream.write(packjoinWithRecords);
|
|
124
|
-
}
|
|
125
|
-
stream.end();
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function decode1(callback) {
|
|
129
|
-
var stream = new PassThrough({objectMode: true});
|
|
130
|
-
var cnt = counter(callback);
|
|
131
|
-
stream.on("data", cnt.inc);
|
|
132
|
-
stream.on("end", cnt.end);
|
|
133
|
-
for (var j = 0; j < opcount; j++) {
|
|
134
|
-
stream.write(msgpack.decode(packed));
|
|
135
|
-
}
|
|
136
|
-
stream.end();
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function decode2(callback) {
|
|
140
|
-
var stream = new PassThrough({objectMode: true});
|
|
141
|
-
var cnt = counter(callback);
|
|
142
|
-
stream.on("data", cnt.inc);
|
|
143
|
-
stream.on("end", cnt.end);
|
|
144
|
-
var decoder = Decoder();
|
|
145
|
-
decoder.on("data", function(chunk) {
|
|
146
|
-
stream.write(chunk);
|
|
147
|
-
});
|
|
148
|
-
decoder.on("end", function() {
|
|
149
|
-
stream.end();
|
|
150
|
-
});
|
|
151
|
-
for (var j = 0; j < opcount / joincount; j++) {
|
|
152
|
-
decoder.decode(packjoin);
|
|
153
|
-
}
|
|
154
|
-
decoder.end();
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function decode3(callback) {
|
|
158
|
-
var stream = msgpack.createDecodeStream();
|
|
159
|
-
var cnt = counter(callback);
|
|
160
|
-
stream.on("data", cnt.inc);
|
|
161
|
-
stream.on("end", cnt.end);
|
|
162
|
-
for (var j = 0; j < opcount / joincount; j++) {
|
|
163
|
-
stream.write(packjoin);
|
|
164
|
-
}
|
|
165
|
-
stream.end();
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function decode4(callback) {
|
|
169
|
-
var stream = new PassThrough({objectMode: true});
|
|
170
|
-
var cnt = counter(callback);
|
|
171
|
-
stream.on("data", cnt.inc);
|
|
172
|
-
stream.on("end", cnt.end);
|
|
173
|
-
for (var j = 0; j < opcount; j++) {
|
|
174
|
-
stream.write(notepack.decode(packed));
|
|
175
|
-
}
|
|
176
|
-
stream.end();
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function rpad(str, len, chr) {
|
|
180
|
-
if (!chr) chr = " ";
|
|
181
|
-
str += "";
|
|
182
|
-
while (str.length < len) str += chr;
|
|
183
|
-
return str;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function lpad(str, len, chr) {
|
|
187
|
-
if (!chr) chr = " ";
|
|
188
|
-
str += "";
|
|
189
|
-
while (str.length < len) str = chr + str;
|
|
190
|
-
return str;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function repeatbuf(buf, cnt) {
|
|
194
|
-
var array = [];
|
|
195
|
-
for (var i = 0; i < cnt; i++) {
|
|
196
|
-
array.push(buf);
|
|
197
|
-
}
|
|
198
|
-
return Buffer.concat(array);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
function counter(callback) {
|
|
202
|
-
var cnt = 0;
|
|
203
|
-
return {buf: b, inc: i, end: e};
|
|
204
|
-
|
|
205
|
-
function b(buf) {
|
|
206
|
-
cnt += buf.length / packsize;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
function i() {
|
|
210
|
-
cnt++;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
function e() {
|
|
214
|
-
cnt = Math.round(cnt);
|
|
215
|
-
callback(null, cnt);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
function run() {
|
|
220
|
-
// task filter
|
|
221
|
-
if (argv.length) {
|
|
222
|
-
list = list.filter(function(pair) {
|
|
223
|
-
var name = pair[0];
|
|
224
|
-
var match = argv.filter(function(grep) {
|
|
225
|
-
return (name.indexOf(grep) > -1);
|
|
226
|
-
});
|
|
227
|
-
return match.length;
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// run tasks repeatedly
|
|
232
|
-
var tasks = [];
|
|
233
|
-
for (var i = 0; i < limit; i++) {
|
|
234
|
-
tasks.push(oneset);
|
|
235
|
-
}
|
|
236
|
-
async.series(tasks, end);
|
|
237
|
-
|
|
238
|
-
// run a series of tasks
|
|
239
|
-
function oneset(callback) {
|
|
240
|
-
async.eachSeries(list, bench, callback);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// run a single benchmark
|
|
244
|
-
function bench(pair, callback) {
|
|
245
|
-
process.stdout.write(".");
|
|
246
|
-
var func = pair[1];
|
|
247
|
-
var start = new Date() - 0;
|
|
248
|
-
func(function(err, cnt) {
|
|
249
|
-
var end = new Date() - 0;
|
|
250
|
-
var array = pair[2] || (pair[2] = []);
|
|
251
|
-
array.push(end - start);
|
|
252
|
-
pair[3] = cnt;
|
|
253
|
-
setTimeout(callback, 100);
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// show result
|
|
258
|
-
function end() {
|
|
259
|
-
var title = "operation (" + opcount + " x " + limit + ")";
|
|
260
|
-
process.stdout.write("\n");
|
|
261
|
-
|
|
262
|
-
// table header
|
|
263
|
-
var COL1 = 48;
|
|
264
|
-
console.log(rpad(title, COL1), "|", " op ", "|", " ms ", "|", " op/s ");
|
|
265
|
-
console.log(rpad("", COL1, "-"), "|", "------:", "|", "----:", "|", "-----:");
|
|
266
|
-
|
|
267
|
-
// table body
|
|
268
|
-
list.forEach(function(pair) {
|
|
269
|
-
var name = pair[0];
|
|
270
|
-
var op = pair[3];
|
|
271
|
-
var array = pair[2];
|
|
272
|
-
array = array.sort(function(a, b) {
|
|
273
|
-
return a > b;
|
|
274
|
-
});
|
|
275
|
-
var fastest = array[0];
|
|
276
|
-
var score = Math.floor(opcount / fastest * 1000);
|
|
277
|
-
console.log(rpad(name, COL1), "|", lpad(op, 7), "|", lpad(fastest, 5), "|", lpad(score, 6));
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
run();
|