Skip to content

Commit 7810884

Browse files
committed
NPM package; changed usage
Old usage: (browser) * serializeMsgPack * deserializeMsgPack New usage: (browser and Node.js) * msgpack.serialize * msgpack.deserialize
1 parent 00ccd86 commit 7810884

8 files changed

+559
-407
lines changed

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright © 2018, Yves Goergen, http://unclassified.software
1+
Copyright © 2019, Yves Goergen, https://unclassified.software
22

33
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
44
associated documentation files (the “Software”), to deal in the Software without restriction,

README.md

+48-19
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,71 @@
11
# msgpack.js
22

3-
This is a [MessagePack](https://msgpack.org) codec written in JavaScript for web browsers (including IE 11). Support for JavaScript servers like Node.js is unknown because I’m not using those, but I see no reason why it shouldn’t work.
3+
This is a [MessagePack](https://msgpack.org) serializer and deserializer written in JavaScript for web browsers (including IE 11) and Node.js.
44

55
It is compact but still fully-featured. This library supports the complete [MessagePack specification](https://github.com/msgpack/msgpack/blob/master/spec.md) released on 2017-08-09, including date/time values. No other extension types are implemented in this library, it’s only the standard types which is perfectly fine for interoperability with MessagePack codecs in other programming languages.
66

77
I’m using the [MessagePack-CSharp](https://github.com/neuecc/MessagePack-CSharp/) library on the server side in my .NET applications.
88

9+
[![NPM](https://img.shields.io/npm/v/msgpack.js.svg)](https://www.npmjs.com/package/msgpack.js)
10+
911
## MessagePack
1012

1113
MessagePack is an efficient binary serialisation format. It lets you exchange data among multiple languages like JSON. But it’s faster and smaller. Small integers are encoded into a single byte, and typical short strings require only one extra byte in addition to the strings themselves.
1214

1315
## Size
1416

15-
This codec is very lightweight. The source code has around **480 lines**, the minified file is below 6.5 kB and can be GZip-compressed to **2.2 kB**.
17+
This library is very lightweight. The source code has around **510 lines** (incl. browser/Node detection), the minified file has 6.6 kB and can be GZip-compressed to **2.4 kB**.
1618

1719
## Performance
1820

1921
The file msgpack-tests.html contains some tests and a benchmark function that compares this library with [msgpack-lite](https://github.com/kawanet/msgpack-lite). Here are the results, in milliseconds (lower is better). All tests done on an Intel Core i7-3770 and Windows 10.
2022

21-
Function | Chrome 70 | | Firefox 63 | | Edge 16 | | IE 11 |  
22-
:------------------|----------:|-----:|-----------:|-----:|--------:|-----:|-------:|-----:
23-
serializeMsgPack | 722 ms | +10% | 1181 ms | −45% | 2739 ms | +50% | 2550 ms| −3%
24-
msgpack.encode | 659 ms | | 2138 ms | | 1829 ms | | 2617 ms|
25-
deserializeMsgPack | 647 ms | +11% | 773 ms | −3% | 816 ms | −49% | 634 ms| −66%
26-
msgpack.decode | 582 ms | | 801 ms | | 1601 ms | | 1870 ms|
23+
Function | Chrome 72 | | Firefox 65 | | Edge 16 | | IE 11 |  
24+
:--------------------------|----------:|-----:|-----------:|-----:|--------:|-----:|-------:|-----:
25+
**msgpack.js serialize** | 702 ms | +6% | 1232 ms | −42% | 2483 ms | +41% | 2493 ms| −3%
26+
msgpack-lite encode | 663 ms | | 2124 ms | | 1762 ms | | 2578 ms|
27+
**msgpack.js deserialize** | 652 ms | +13% | 869 ms | +5% | 821 ms | −48% | 651 ms| −68%
28+
msgpack-lite decode | 577 ms | | 827 ms | | 1587 ms | | 2021 ms|
2729

2830
The numbers show that this library is comparable with msgpack-lite. In Chrome it’s only 10% slower. But serializing in Firefox and deserializing in Microsoft browsers is twice as fast.
2931

3032
## Usage
3133

32-
The source file contains two public functions: `serializeMsgPack` and `deserializeMsgPack`. The first can be called with any data and returns the encoded bytes. The second works in reverse, taking the encoded bytes and returning the runtime value.
34+
### Browser
35+
36+
In browsers, a global `msgpack` object is created that contains the functions `serialize` and `deserialize`. The first can be called with any data and returns the serialized bytes. The second works in reverse, taking the serialized bytes and returning the runtime value.
37+
38+
Include the JavaScript file into your HTML document like this:
39+
40+
```html
41+
<script src="msgpack.min.js"></script>
42+
```
43+
44+
You can use the library functions after loading the script.
45+
46+
If there should be a naming conflict with another library you want to load, you can change the global object name from `msgpack` to something else by setting `msgpackJsName` before loading the script file:
47+
48+
```html
49+
<script>
50+
msgpackJsName = "msgpackJs";
51+
</script>
52+
<script src="msgpack.min.js"></script>
53+
```
54+
55+
### Node.js
56+
57+
In Node.js, these functions are exported in the object you get from the `require` function.
58+
59+
```js
60+
var msgpack = require('msgpack.js');
61+
```
62+
63+
### Example
3364

3465
Here’s a simple example:
3566

3667
```js
37-
// Define some data to encode
68+
// Define some data
3869
var sourceData = {
3970
number: 123,
4071
number2: -0.129,
@@ -45,20 +76,18 @@ var sourceData = {
4576
time: Date.now()
4677
};
4778

48-
// Encode to byte array
49-
var encodedBytes = serializeMsgPack(sourceData);
79+
// Serialize to byte array
80+
var bytes = msgpack.serialize(sourceData);
5081

51-
// Decode again
52-
var decodedData = deserializeMsgPack(encodedBytes);
82+
// Deserialize again
83+
var deserializedData = msgpack.deserialize(bytes);
5384
```
5485

55-
Include the JavaScript file into your HTML document like this:
86+
### Compatibility
5687

57-
```html
58-
<script src="msgpack.min.js"></script>
59-
```
88+
You can also use the functions `encode` and `decode` which are aliases to `serialize` and `deserialize`. This makes it easier to replace other libraries that use these function names with msgpack.js.
6089

61-
You can use the codec functions after loading the script. No additional configuration required.
90+
New projects should use the preferred (and more precisely named) `serialize` and `deserialize` functions though.
6291

6392
## License
6493

msgpack-tests.html

+6-1
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,13 @@
2121
<p id="log">
2222
</p>
2323

24-
<script src="msgpack.js"></script>
2524
<script src="https://rawgit.com/kawanet/msgpack-lite/master/dist/msgpack.min.js"></script>
25+
<script>
26+
// Rename library object to load it side by side
27+
window.msgpackLite = msgpack;
28+
delete msgpack;
29+
</script>
30+
<script src="msgpack.js"></script>
2631
<script src="msgpack-tests.js"></script>
2732
</body>
2833
</html>

msgpack-tests.js

+68-21
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ function testData(data) {
2323
console.log("data =", data);
2424

2525
// Perform the conversion and back
26-
let bin = serializeMsgPack(data);
26+
let bin = msgpack.serialize(data);
2727
let binStr = format(bin, true);
2828

2929
logLine("bin = " + binStr);
@@ -35,8 +35,8 @@ function testData(data) {
3535
//logLine("bin = " + format(bin, true));
3636
//console.log("bin =", bin);
3737

38-
//let data2 = msgpack.decode(bin); // external library: kawanet/msgpack-lite
39-
let data2 = deserializeMsgPack(bin); // this library
38+
//let data2 = msgpackLite.decode(bin); // external library: kawanet/msgpack-lite
39+
let data2 = msgpack.deserialize(bin); // this library
4040

4141
// NOTE: Workaround for datetime decoding which is not supported by kawanet/msgpack-lite
4242
//if (data2.type === 255 && data2.buffer.length === 4) {
@@ -98,7 +98,7 @@ function testData(data) {
9898
// Runs several functions in a loop to measure the time spent.
9999
function benchmark() {
100100
// Define the data to test with
101-
let data = {
101+
const data = {
102102
number1: 1,
103103
number2: 20,
104104
number3: 200,
@@ -142,11 +142,11 @@ function benchmark() {
142142
logLine();
143143

144144
// Convert the data to MsgPack and back to verify correctness
145-
let bin = serializeMsgPack(data);
146-
//let bin = msgpack.encode(data);
145+
let bin = msgpack.serialize(data);
146+
//let bin = msgpackLite.encode(data);
147147

148-
let bin1 = serializeMsgPack(data);
149-
let bin2 = new Uint8Array(msgpack.encode(data));
148+
let bin1 = msgpack.serialize(data);
149+
let bin2 = new Uint8Array(msgpackLite.encode(data));
150150
let binStr1 = format(bin1, true);
151151
let binStr2 = format(bin2, true);
152152
if (binStr1 !== binStr2) {
@@ -159,7 +159,7 @@ function benchmark() {
159159
}
160160
logLine();
161161

162-
let data2Str = format(deserializeMsgPack(bin));
162+
let data2Str = format(msgpack.deserialize(bin));
163163
if (dataStr !== data2Str) {
164164
logLine("Mismatch between original and processed data:");
165165
logLine("<b>original:</b> " + dataStr);
@@ -170,7 +170,7 @@ function benchmark() {
170170
}
171171
logLine();
172172

173-
data2Str = format(msgpack.decode(bin));
173+
data2Str = format(msgpackLite.decode(bin));
174174
if (dataStr !== data2Str) {
175175
logLine("Mismatch between original and processed data:");
176176
logLine("<b>original:</b> " + dataStr);
@@ -188,31 +188,78 @@ function benchmark() {
188188

189189
// Start the first iteration without blocking the browser for the entire benchmark duration
190190
logLine("Starting benchmark...");
191+
192+
let type = 1;
193+
let results = [];
191194
setTimeout(run, 100);
192195

193196
function run() {
197+
if (step === 0) {
198+
switch (type) {
199+
case 1: logLine("<b>msgpack.js serialize</b>"); break;
200+
case 2: logLine("<b>msgpack-lite encode</b>"); break;
201+
case 3: logLine("<b>msgpack.js deserialize</b>"); break;
202+
case 4: logLine("<b>msgpack-lite decode</b>"); break;
203+
}
204+
}
205+
194206
step++;
195207
let t0 = Math.round(performance.now());
196208
// NOTE: performance.now is only accurate to a few milliseconds. This is compensated by making the test run longer.
197-
for (let i = 0; i < 20000; i++) {
198-
// Call the function to benchmark
199-
let bin2 = serializeMsgPack(data);
200-
//let bin2 = msgpack.encode(data);
201-
//let data2 = deserializeMsgPack(bin);
202-
//let data2 = msgpack.decode(bin);
209+
// Call the function to benchmark
210+
switch (type) {
211+
case 1:
212+
for (let i = 0; i < 20000; i++) {
213+
var bin2 = msgpack.serialize(data);
214+
}
215+
break;
216+
case 2:
217+
for (let i = 0; i < 20000; i++) {
218+
var bin2 = msgpackLite.encode(data);
219+
}
220+
break;
221+
case 3:
222+
for (let i = 0; i < 20000; i++) {
223+
var data2 = msgpack.deserialize(bin);
224+
}
225+
break;
226+
case 4:
227+
for (let i = 0; i < 20000; i++) {
228+
var data2 = msgpackLite.decode(bin);
229+
}
230+
break;
203231
}
204232
let t1 = Math.round(performance.now());
205233
logLine(step + "/" + steps + ": " + (t1 - t0) + " ms");
206-
if (minTime === -1)
234+
if (minTime === -1 || t1 - t0 < minTime)
207235
minTime = t1 - t0;
208-
else
209-
minTime = Math.min(minTime, t1 - t0);
210236

211237
// Stop after a number of iterations and show the minimum time spent
212-
if (step < steps)
238+
if (step < steps) {
213239
setTimeout(run, 100);
214-
else
240+
}
241+
else {
215242
logLine("Minimum time: <b>" + minTime + " ms</b>");
243+
results.push(minTime);
244+
245+
// Next phase
246+
type++;
247+
step = 0;
248+
minTime = -1;
249+
if (type <= 4) {
250+
setTimeout(run, 100);
251+
}
252+
else {
253+
logLine("<b>All results:</b>");
254+
let percent1 = Math.round((results[0] / results[1] * 100) - 100);
255+
let percent2 = Math.round((results[2] / results[3] * 100) - 100);
256+
logLine("msgpack.js serialize: <b>" + results[0] + " ms</b>, " + (percent1 >= 0 ? "+" : "") + percent1 + "%");
257+
logLine("msgpack-lite encode: <b>" + results[1] + " ms</b>");
258+
logLine("msgpack.js deserialize: <b>" + results[2] + " ms</b>, " + (percent2 >= 0 ? "+" : "") + percent2 + "%");
259+
logLine("msgpack-lite decode: <b>" + results[3] + " ms</b>");
260+
}
261+
}
262+
window.scroll(0, 10000);
216263
}
217264
}
218265

0 commit comments

Comments
 (0)