Skip to content

Commit 50011dd

Browse files
Merge branch 'master' of github.com:msgpack/msgpack-javascript
2 parents cffbea3 + 3d22f98 commit 50011dd

File tree

13 files changed

+249
-142
lines changed

13 files changed

+249
-142
lines changed

.travis.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,37 @@
11
language: node_js
22
node_js:
33
- lts/*
4+
addons:
5+
firefox: latest
46
env:
57
matrix:
8+
- BROWSER=
9+
- BROWSER=FirefoxHeadless
610
- BROWSER=slChrome
711
- BROWSER=slFirefox
812
- BROWSER=slSafari
913
- BROWSER=slIE
1014
- BROWSER=slEdge
1115
- BROWSER=slIos
1216
- BROWSER=slAndroid
13-
- BROWSER=
1417
global:
1518
# SAUCE_USERNAME
1619
- secure: J+FOPE/vVK6yzVXHVE7xibFV/hV+Ehc78MBADLlE10YIY7Ag6JkVeomgqRFB9I8zFzj5DALkpzOLGx4iIrFs6iYiNnEcl39fkm8myHl8xIuW+KHt5QOsCtM5qmvfSEZhJV+La0lSzFicjY9VX90VLZvJOHIbiCvIFRoxnwYVw6o=
1720
# SAUCE_ACCESS_KEY
1821
- secure: ay3CSAjya+UQDi0RulLIl6q25oobwLsjLbdkeASgjBq0qN5dXgFgEpBjecBxFqPGrwzzCj9K9fR81NWV80EjLkGdcfN0oGx0wvsOo2C2ulWGHc1dRgKUnMKAA2TL3br14KMfmGn6fmr+fA7Vq+qWajQpExlG0Kuw68C9iNuKIQw=
22+
matrix:
23+
fast_finish: true
24+
allow_failures:
25+
# Because Travis CI does not expose credentials to pull-request builds from forked repositories.
26+
# https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
27+
- env: BROWSER=slChrome
28+
- env: BROWSER=slFirefox
29+
- env: BROWSER=slSafari
30+
- env: BROWSER=slIE
31+
- env: BROWSER=slEdge
32+
- env: BROWSER=slIos
33+
- env: BROWSER=slAndroid
34+
1935
cache: npm
2036
install: |
2137
if [ "${BROWSER}" = "" ]

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
This is the revision history of @msgpack/msgpack
22

3+
## v1.2.3 2019/05/29
4+
5+
https://github.com/msgpack/msgpack-javascript/compare/v1.2.2...v1.2.3
6+
7+
* More optimizations for string decoding performance
8+
9+
## v1.2.2 2019/05/29
10+
11+
https://github.com/msgpack/msgpack-javascript/compare/v1.2.1...v1.2.2
12+
13+
* Improved array decoding performance ([#32](https://github.com/msgpack/msgpack-javascript/pull/32) by @sergeyzenchenko)
14+
* Improved string decoding performance with TextDecoder ([#34](https://github.com/msgpack/msgpack-javascript/pull/34) by @sergeyzenchenko)
15+
316
## v1.2.1 2019/05/26
417

518
https://github.com/msgpack/msgpack-javascript/compare/v1.2.0...v1.2.1

README.md

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,50 @@ const encoded: = encode(value, { extensionCodec });
152152
deepStrictEqual(decode(encoded, { extensionCodec }), value);
153153
```
154154

155+
#### The temporal module as timestamp extensions
156+
157+
This library maps `Date` to the MessagePack timestamp extension, but you re-map the [temporal module](https://github.com/tc39/proposal-temporal) to the timestamp ext like this:
158+
159+
```typescript
160+
import { Instant } from "@std-proposal/temporal";
161+
import { deepStrictEqual } from "assert";
162+
import {
163+
encode,
164+
decode,
165+
ExtensionCodec,
166+
EXT_TIMESTAMP,
167+
encodeTimeSpecToTimestamp,
168+
decodeTimestampToTimeSpec,
169+
} from "@msgpack/msgpack";
170+
171+
const extensionCodec = new ExtensionCodec();
172+
extensionCodec.register({
173+
type: EXT_TIMESTAMP, // override the default behavior!
174+
encode: (input: any) => {
175+
if (input instanceof Instant) {
176+
const sec = input.seconds;
177+
const nsec = Number(input.nanoseconds - BigInt(sec) * BigInt(1e9));
178+
return encodeTimeSpecToTimestamp({ sec, nsec });
179+
} else {
180+
return null;
181+
}
182+
},
183+
decode: (data: Uint8Array) => {
184+
const timeSpec = decodeTimestampToTimeSpec(data);
185+
const sec = BigInt(timeSpec.sec);
186+
const nsec = BigInt(timeSpec.nsec);
187+
return Instant.fromEpochNanoseconds(sec * BigInt(1e9) + nsec);
188+
},
189+
});
190+
191+
const instant = Instant.fromEpochMilliseconds(Date.now());
192+
const encoded = encode(instant, { extensionCodec });
193+
const decoded = decode(encoded, { extensionCodec });
194+
deepStrictEqual(decoded, instant);
195+
```
196+
197+
This will be default after the temporal module is implemented in major browsers, which is not a near-future, though.
198+
155199
## MessagePack Mapping Table
156200

157201
The following table shows how JavaScript values are mapped to [MessagePack formats](https://github.com/msgpack/msgpack/blob/master/spec.md) and vice versa.
@@ -193,17 +237,17 @@ NodeJS v10 is required, but NodeJS v12 or later is recommended because it includ
193237

194238
## Benchmark
195239

196-
Benchmark on NodeJS/v12.1.0
240+
Benchmark on NodeJS/v12.3.1
197241

198242
operation | op | ms | op/s
199243
----------------------------------------------------------------- | ------: | ----: | ------:
200-
buf = Buffer.from(JSON.stringify(obj)); | 493600 | 5000 | 98720
201-
buf = JSON.stringify(obj); | 959600 | 5000 | 191920
202-
obj = JSON.parse(buf); | 346100 | 5000 | 69220
203-
buf = require("msgpack-lite").encode(obj); | 358300 | 5000 | 71660
204-
obj = require("msgpack-lite").decode(buf); | 270400 | 5000 | 54080
205-
buf = require("@msgpack/msgpack").encode(obj); | 594300 | 5000 | 118860
206-
obj = require("@msgpack/msgpack").decode(buf); | 343100 | 5000 | 68620
244+
buf = Buffer.from(JSON.stringify(obj)); | 497600 | 5000 | 99520
245+
buf = JSON.stringify(obj); | 969500 | 5000 | 193900
246+
obj = JSON.parse(buf); | 345300 | 5000 | 69060
247+
buf = require("msgpack-lite").encode(obj); | 369100 | 5000 | 73820
248+
obj = require("msgpack-lite").decode(buf); | 278900 | 5000 | 55780
249+
buf = require("@msgpack/msgpack").encode(obj); | 556900 | 5000 | 111380
250+
obj = require("@msgpack/msgpack").decode(buf); | 502200 | 5000 | 100440
207251

208252
Note that `Buffer.from()` for `JSON.stringify()` is added to emulate I/O where a JavaScript string must be converted into a byte array encoded in UTF-8, whereas MessagePack's `encode()` returns a byte array.
209253

benchmark/decode-string.ts

Lines changed: 36 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,45 @@
11
/* eslint-disable no-console */
2-
import { utf8Encode, utf8Count, utf8Decode } from "../src/utils/utf8";
2+
import { utf8Encode, utf8Count, utf8DecodeJs, utf8DecodeTD } from "../src/utils/utf8";
33
import { utf8DecodeWasm } from "../src/wasmFunctions";
44

55
// @ts-ignore
66
import Benchmark from "benchmark";
77

8-
const textDecoder = new TextDecoder();
9-
10-
const dataSet = [10, 100, 200, 1_000, 10_000, 100_000].map((n) => {
11-
return "a".repeat(n);
12-
});
13-
14-
for (const str of dataSet) {
15-
const byteLength = utf8Count(str);
16-
const bytes = new Uint8Array(new ArrayBuffer(byteLength));
17-
utf8Encode(str, bytes, 0);
18-
19-
console.log(`\n## string length=${str.length} byteLength=${byteLength}\n`);
20-
21-
const suite = new Benchmark.Suite();
22-
23-
const N = Math.round(100_0000 / str.length);
24-
25-
// use the result to avoid void-context optimizations
26-
let count = 0;
27-
28-
suite.add("utf8Decode", () => {
29-
if (utf8Decode(bytes, 0, byteLength) !== str) {
30-
throw new Error("wrong result!");
31-
}
32-
});
33-
34-
suite.add("utf8DecodeWasm", () => {
35-
if (utf8DecodeWasm(bytes, 0, byteLength) !== str) {
36-
throw new Error("wrong result!");
37-
}
38-
});
39-
40-
suite.add("TextDecoder", () => {
41-
if (textDecoder.decode(bytes.subarray(0, byteLength)) !== str) {
42-
throw new Error("wrong result!");
43-
}
44-
});
45-
suite.on("cycle", (event: any) => {
46-
console.log(String(event.target));
8+
for (const baseStr of ["A", "あ", "🌏"]) {
9+
const dataSet = [10, 100, 200, 1_000, 10_000, 100_000].map((n) => {
10+
return baseStr.repeat(n);
4711
});
4812

49-
suite.run();
13+
for (const str of dataSet) {
14+
const byteLength = utf8Count(str);
15+
const bytes = new Uint8Array(new ArrayBuffer(byteLength));
16+
utf8Encode(str, bytes, 0);
17+
18+
console.log(`\n## string "${baseStr}" x ${str.length} (byteLength=${byteLength})\n`);
19+
20+
const suite = new Benchmark.Suite();
21+
22+
suite.add("utf8DecodeJs", () => {
23+
if (utf8DecodeJs(bytes, 0, byteLength) !== str) {
24+
throw new Error("wrong result!");
25+
}
26+
});
27+
28+
suite.add("utf8DecodeWasm", () => {
29+
if (utf8DecodeWasm(bytes, 0, byteLength) !== str) {
30+
throw new Error("wrong result!");
31+
}
32+
});
33+
34+
suite.add("TextDecoder", () => {
35+
if (utf8DecodeTD(bytes, 0, byteLength) !== str) {
36+
throw new Error("wrong result!");
37+
}
38+
});
39+
suite.on("cycle", (event: any) => {
40+
console.log(String(event.target));
41+
});
42+
43+
suite.run();
44+
}
5045
}

package-lock.json

Lines changed: 31 additions & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)