Skip to content

Commit 9a912d6

Browse files
committed
speed up
Signed-off-by: uupaa <uupaa.js@gmail.com>
1 parent 264bd02 commit 9a912d6

File tree

3 files changed

+111
-45
lines changed

3 files changed

+111
-45
lines changed

msgpack.js

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ var _ie = /MSIE/.test(navigator.userAgent),
2424
_num2b64 = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
2525
"abcdefghijklmnopqrstuvwxyz0123456789+/").split(""),
2626
_sign = { 8: 0x80, 16: 0x8000, 32: 0x80000000 },
27-
_8bits = /[01]{8}/g;
27+
_pooledArray = [],
28+
_IEEE754positive = /^.(.{8})(.{8})(.{8})(.{8})(.{8})(.{8})(.{8})(.{8})$/,
29+
_IEEE754negative = /^(.{8})(.{8})(.{8})(.{8})(.{8})(.{8})(.{8})(.{8})$/;
2830

2931
// for WebWorkers Code Block
3032
self.importScripts && (onmessage = function(event) {
@@ -42,21 +44,10 @@ function msgpackpack(data, // @param Mix:
4244
// [1][mix to String] msgpack.pack({}, true) -> "..."
4345
// [2][mix to ByteArray] msgpack.pack({}) -> [...]
4446

45-
var byteArray = encode([], data), rv, i, iz, num2bin = _num2bin;
47+
var byteArray = encode([], data);
4648

47-
if (toString) {
48-
// http://d.hatena.ne.jp/uupaa/20101128
49-
try {
50-
return String.fromCharCode.apply(this, byteArray); // toString
51-
} catch(err) {
52-
; // avoid "Maximum call stack size exceeded"
53-
}
54-
for (rv = [], i = 0, iz = byteArray.length; i < iz; ++i) {
55-
rv[i] = num2bin[byteArray[i]];
56-
}
57-
return rv.join("");
58-
}
59-
return byteArray;
49+
return toString ? byteArrayToByteString(byteArray)
50+
: byteArray;
6051
}
6152

6253
// msgpack.unpack
@@ -73,7 +64,7 @@ function msgpackunpack(data) { // @param BinaryString/ByteArray:
7364
// inner - encoder
7465
function encode(rv, // @param ByteArray: result
7566
mix) { // @param Mix: source data
76-
var size = 0, i = 0, iz, c, hash, pos,
67+
var size = 0, i = 0, iz, c, ary, hash, pos,
7768
high, low, i64 = 0, sign, exp, frac;
7869

7970
if (mix == null) { // null or undefined
@@ -135,7 +126,8 @@ function encode(rv, // @param ByteArray: result
135126
sign && (mix *= -1);
136127

137128
// add offset 1023 to ensure positive
138-
exp = Math.log(mix) / Math.LN2 + 1023 | 0;
129+
// 0.6931471805599453 = Math.LN2;
130+
exp = ((Math.log(mix) / 0.6931471805599453) + 1023) | 0;
139131

140132
// shift 52 - (exp - 1023) bits to make integer part exactly 53 bits,
141133
// then throw away trash less than decimal point
@@ -144,15 +136,13 @@ function encode(rv, // @param ByteArray: result
144136

145137
// exp is between 1 and 2047. make it 11 bits
146138
// http://d.hatena.ne.jp/uupaa/20101128
147-
if (!sign) {
148-
ary = ((exp + 4096).toString(2).slice(1) + frac).match(_8bits);
149-
} else {
150-
ary = ((exp + 2048).toString(2) + frac).match(_8bits);
151-
}
152-
rv.push(0xcb, hash[ary[0]], hash[ary[1]],
153-
hash[ary[2]], hash[ary[3]],
154-
hash[ary[4]], hash[ary[5]],
155-
hash[ary[6]], hash[ary[7]]);
139+
_pooledArray = !sign ? _IEEE754positive.exec((exp + 4096).toString(2) + frac)
140+
: _IEEE754negative.exec((exp + 2048).toString(2) + frac);
141+
ary = _pooledArray; // alias
142+
rv.push(0xcb, hash[ary[1]], hash[ary[2]],
143+
hash[ary[3]], hash[ary[4]],
144+
hash[ary[5]], hash[ary[6]],
145+
hash[ary[7]], hash[ary[8]]);
156146
}
157147
break;
158148
case "string":
@@ -218,7 +208,7 @@ function encode(rv, // @param ByteArray: result
218208

219209
// inner - decoder
220210
function decode() { // @return Mix:
221-
var rv, undef, size, i = 0, iz, msb = 0, c, sign, exp, frac, key,
211+
var rv, undef, size, i = 0, iz, msb = 0, c, sign, exp, frac, key, ary,
222212
that = this,
223213
data = that.data,
224214
type = data[++that.index];
@@ -284,18 +274,21 @@ function decode() { // @return Mix:
284274
case 0xa0: i = that.index + 1; // raw
285275
that.index += size;
286276
// utf8.decode
287-
for (rv = [], ri = -1, iz = i + size; i < iz; ++i) {
277+
_pooledArray = [];
278+
ary = _pooledArray; // alias
279+
for (iz = i + size; i < iz; ++i) {
288280
c = data[i]; // first byte
289281
if (c < 0x80) { // ASCII(0x00 ~ 0x7f)
290-
rv[++ri] = c;
282+
ary.push(c);
291283
} else if (c < 0xe0) {
292-
rv[++ri] = (c & 0x1f) << 6 | (data[++i] & 0x3f);
284+
ary.push((c & 0x1f) << 6 | (data[++i] & 0x3f));
293285
} else if (c < 0xf0) {
294-
rv[++ri] = (c & 0x0f) << 12 | (data[++i] & 0x3f) << 6
295-
| (data[++i] & 0x3f);
286+
ary.push((c & 0x0f) << 12 | (data[++i] & 0x3f) << 6
287+
| (data[++i] & 0x3f));
296288
}
297289
}
298-
return String.fromCharCode.apply(null, rv);
290+
return ary.length < 1024000 ? String.fromCharCode.apply(null, ary)
291+
: byteArrayToByteString(ary);
299292
case 0xdf: size = readByte(that, 4); // map 32
300293
case 0xde: size === undef && (size = readByte(that, 2)); // map 16
301294
case 0x80: for (rv = {}; i < size; ++i) { // map
@@ -374,6 +367,23 @@ function setType(rv, // @param ByteArray: result
374367
}
375368
}
376369

370+
// inner - byteArray To ByteString
371+
function byteArrayToByteString(byteArray) { // @param ByteArray
372+
// @return String
373+
// http://d.hatena.ne.jp/uupaa/20101128
374+
try {
375+
return String.fromCharCode.apply(this, byteArray); // toString
376+
} catch(err) {
377+
; // avoid "Maximum call stack size exceeded"
378+
}
379+
var rv = [], i = 0, iz = byteArray.length, num2bin = _num2bin;
380+
381+
for (; i < iz; ++i) {
382+
rv[i] = num2bin[byteArray[i]];
383+
}
384+
return rv.join("");
385+
}
386+
377387
// msgpack.download - load from server
378388
function msgpackdownload(url, // @param String:
379389
option, // @param Hash: { worker, timeout, before, after }

test/100000.js

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

test/bench.htm

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
<script src="../msgpack.js"></script>
55
<script src="uupaa.js"></script>
66
<script src="10000.js"></script>
7+
<!--
8+
<script src="100000.js"></script>
9+
-->
710
<script>
811

912

1013
uu.ready(function() {
1114
if (uu.ie678) {
12-
alert(1);
1315
uu.id("Biggest").disabled = true;
1416
}
1517
});
@@ -95,17 +97,20 @@
9597
for (i = 0; i < size; ++i) {
9698
obj[i] = addItem();
9799
}
98-
// uu.id("json").value = uu.json(obj, true);
99-
uu.id("json").value = "(*snip*)";
100-
uu.log("size = " + size);
100+
if (0) {
101+
uu.id("json").value = uu.json(obj, true);
102+
} else {
103+
uu.id("json").value = "(*snip*)";
104+
}
105+
uu.log("data size = " + size);
101106

102107
mix = obj;
103108
}
104109

105-
function solid(solidData) {
110+
function solid(solidData, dataSize) {
106111
mix = solidData;
107112
uu.id("json").value = "(*snip*)";
108-
uu.log("size = 10000");
113+
uu.log("data size = " + dataSize);
109114
}
110115
</script>
111116
</head><body>
@@ -124,13 +129,11 @@ <h1>Benchmark</h1>
124129
</tr>
125130
<tr>
126131
<td>
127-
<input type="button" disabled="disabled" value="Load 100000" onclick="solid(solid100000)" />
128-
<input type="button" value="Load 10000" onclick="solid(solid10000)" />
132+
<!--
133+
<input type="button" value="Load 100000" onclick="solid(solid100000, 100000)" />
134+
-->
135+
<input type="button" value="Load 10000" onclick="solid(solid10000, 10000)" />
129136
<br />
130-
<input type="button" id="Biggest" value="Create 100000" onclick="create(100000)" />
131-
<input type="button" value="Create 10000" onclick="create(10000)" />
132-
<input type="button" value="Create 1000" onclick="create(1000)" />
133-
<input type="button" value="Create 10" onclick="create(10)" />
134137
</td>
135138
<td> -&gt; </td>
136139
<td>
@@ -147,6 +150,11 @@ <h1>Benchmark</h1>
147150
</tr>
148151
</table>
149152
<textarea id="json" cols="120" rows="5"></textarea>
153+
<input type="button" id="Biggest" value="Create 100000" onclick="create(100000)" />
154+
<input type="button" value="Create 10000" onclick="create(10000)" />
155+
<input type="button" value="Create 1000" onclick="create(1000)" />
156+
<input type="button" value="Create 10" onclick="create(10)" />
157+
150158

151159

152160

0 commit comments

Comments
 (0)