Skip to content

Commit 1e26857

Browse files
committed
add IEEE754 benchmark
Signed-off-by: uupaa <[email protected]>
1 parent cce158e commit 1e26857

File tree

3 files changed

+285
-24
lines changed

3 files changed

+285
-24
lines changed

msgpack.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ function encode(rv, // @param ByteArray: result
154154
// 3 2 21 1 8 0
155155
// 1 4 09 6
156156
low = frac & 0xffffffff;
157+
sign && (exp |= 0x800);
157158
high = ((frac / 0x100000000) & 0xfffff) | (exp << 20);
158-
sign && (high |= 0x80000000);
159159

160160
rv.push(0xcb, (high >> 24) & 0xff, (high >> 16) & 0xff,
161161
(high >> 8) & 0xff, high & 0xff,

test/IEEE754.bench.htm

+275
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>IEEE754</title>
4+
<pre id="log"></pre>
5+
<script>
6+
7+
function print(msg) {
8+
document.getElementById('log').innerHTML += msg + '\n';
9+
}
10+
11+
window.onload = function() {
12+
// prepare
13+
var _bit2num = {};
14+
for (var i = 0; i < 0x100; ++i) {
15+
_bit2num[("0000000" + i.toString(2)).slice(-8)] = i;
16+
}
17+
var _IEEE754positive = /^.(.{8})(.{8})(.{8})(.{8})(.{8})(.{8})(.{8})(.{8})$/;
18+
var _IEEE754negative = /^(.{8})(.{8})(.{8})(.{8})(.{8})(.{8})(.{8})(.{8})$/;
19+
20+
var input = [];
21+
for (var i = 1; i < 100000; i += 2) {
22+
input[i - 1] = i / Math.PI;
23+
input[i] = - i / Math.PI;
24+
}
25+
26+
function test1(input) {
27+
var rv = [], mix, hash, sign, exp, frac, ary, _pooledArray;
28+
29+
for (var i = 0, l = input.length; i < l; i++) {
30+
mix = input[i];
31+
32+
hash = _bit2num;
33+
sign = mix < 0;
34+
sign && (mix *= -1);
35+
36+
// add offset 1023 to ensure positive
37+
// 0.6931471805599453 = Math.LN2;
38+
exp = ((Math.log(mix) / 0.6931471805599453) + 1023) | 0;
39+
40+
// shift 52 - (exp - 1023) bits to make integer part exactly 53 bits,
41+
// then throw away trash less than decimal point
42+
frac = (Math.floor(mix * Math.pow(2, 52 + 1023 - exp))).
43+
toString(2).slice(1);
44+
45+
// exp is between 1 and 2047. make it 11 bits
46+
// http://d.hatena.ne.jp/uupaa/20101128
47+
_pooledArray = !sign ? _IEEE754positive.exec((exp + 4096).toString(2) + frac)
48+
: _IEEE754negative.exec((exp + 2048).toString(2) + frac);
49+
ary = _pooledArray; // alias
50+
rv.push(0xcb, hash[ary[1]], hash[ary[2]],
51+
hash[ary[3]], hash[ary[4]],
52+
hash[ary[5]], hash[ary[6]],
53+
hash[ary[7]], hash[ary[8]]);
54+
}
55+
56+
return rv;
57+
}
58+
59+
60+
function test2(input) {
61+
var rv = [], mix, sign, exp, frac, upper, r1, r2, r3, r4, r5 ,r6, r7, r8;
62+
for (var i = 0, l = input.length; i < l; i++) {
63+
mix = input[i];
64+
65+
sign = mix < 0;
66+
sign && (mix *= -1);
67+
68+
// add offset 1023 to ensure positive
69+
// 0.6931471805599453 = Math.LN2;
70+
exp = ((Math.log(mix) / 0.6931471805599453) + 1023) | 0;
71+
72+
// shift 52 - (exp - 1023) bits to make integer part exactly 53 bits,
73+
// then throw away trash less than decimal point
74+
frac = (Math.floor(mix * Math.pow(2, 52 + 1023 - exp))).toString(2);
75+
76+
// 13 bits = "1" (no meaning) + 1 bit (sign) + 11 bits (exp)
77+
// 6144 = 2048 + 4096 = 1100000000000 (2)
78+
upper = (exp + (sign ? 6144 : 4096)).toString(2);
79+
80+
// charCode for '0' => 48, '1' => 49
81+
82+
r8 = ((frac.charCodeAt(52) - 48) ) + ((frac.charCodeAt(51) - 48) << 1) +
83+
((frac.charCodeAt(50) - 48) << 2) + ((frac.charCodeAt(49) - 48) << 3) +
84+
((frac.charCodeAt(48) - 48) << 4) + ((frac.charCodeAt(47) - 48) << 5) +
85+
((frac.charCodeAt(46) - 48) << 6) + ((frac.charCodeAt(45) - 48) << 7) ;
86+
87+
r7 = ((frac.charCodeAt(44) - 48) ) + ((frac.charCodeAt(43) - 48) << 1) +
88+
((frac.charCodeAt(42) - 48) << 2) + ((frac.charCodeAt(41) - 48) << 3) +
89+
((frac.charCodeAt(40) - 48) << 4) + ((frac.charCodeAt(39) - 48) << 5) +
90+
((frac.charCodeAt(38) - 48) << 6) + ((frac.charCodeAt(37) - 48) << 7) ;
91+
92+
r6 = ((frac.charCodeAt(36) - 48) ) + ((frac.charCodeAt(35) - 48) << 1) +
93+
((frac.charCodeAt(34) - 48) << 2) + ((frac.charCodeAt(33) - 48) << 3) +
94+
((frac.charCodeAt(32) - 48) << 4) + ((frac.charCodeAt(31) - 48) << 5) +
95+
((frac.charCodeAt(30) - 48) << 6) + ((frac.charCodeAt(29) - 48) << 7) ;
96+
97+
r5 = ((frac.charCodeAt(28) - 48) ) + ((frac.charCodeAt(27) - 48) << 1) +
98+
((frac.charCodeAt(26) - 48) << 2) + ((frac.charCodeAt(25) - 48) << 3) +
99+
((frac.charCodeAt(24) - 48) << 4) + ((frac.charCodeAt(23) - 48) << 5) +
100+
((frac.charCodeAt(22) - 48) << 6) + ((frac.charCodeAt(21) - 48) << 7) ;
101+
102+
r4 = ((frac.charCodeAt(20) - 48) ) + ((frac.charCodeAt(19) - 48) << 1) +
103+
((frac.charCodeAt(18) - 48) << 2) + ((frac.charCodeAt(17) - 48) << 3) +
104+
((frac.charCodeAt(16) - 48) << 4) + ((frac.charCodeAt(15) - 48) << 5) +
105+
((frac.charCodeAt(14) - 48) << 6) + ((frac.charCodeAt(13) - 48) << 7) ;
106+
107+
r3 = ((frac.charCodeAt(12) - 48) ) + ((frac.charCodeAt(11) - 48) << 1) +
108+
((frac.charCodeAt(10) - 48) << 2) + ((frac.charCodeAt( 9) - 48) << 3) +
109+
((frac.charCodeAt( 8) - 48) << 4) + ((frac.charCodeAt( 7) - 48) << 5) +
110+
((frac.charCodeAt( 6) - 48) << 6) + ((frac.charCodeAt( 5) - 48) << 7) ;
111+
112+
r2 = ((frac.charCodeAt( 4) - 48) ) + ((frac.charCodeAt( 3) - 48) << 1) +
113+
((frac.charCodeAt( 2) - 48) << 2) + ((frac.charCodeAt( 1) - 48) << 3) +
114+
((upper.charCodeAt(12) - 48) << 4) + ((upper.charCodeAt(11) - 48) << 5) +
115+
((upper.charCodeAt(10) - 48) << 6) + ((upper.charCodeAt( 9) - 48) << 7) ;
116+
117+
r1 = ((upper.charCodeAt( 8) - 48) ) + ((upper.charCodeAt( 7) - 48) << 1) +
118+
((upper.charCodeAt( 6) - 48) << 2) + ((upper.charCodeAt( 5) - 48) << 3) +
119+
((upper.charCodeAt( 4) - 48) << 4) + ((upper.charCodeAt( 3) - 48) << 5) +
120+
((upper.charCodeAt( 2) - 48) << 6) + ((upper.charCodeAt( 1) - 48) << 7) ;
121+
122+
rv.push(0xcb, r1, r2, r3, r4, r5, r6, r7, r8);
123+
}
124+
125+
return rv;
126+
}
127+
128+
function test3(input) {
129+
var rv = [], mix, sign, exp, frac, r1, r2, r3, r4, r5 ,r6, r7, r8;
130+
for (var i = 0, l = input.length; i < l; i++) {
131+
mix = input[i];
132+
133+
sign = mix < 0;
134+
sign && (mix *= -1);
135+
136+
// exp => 11 bits
137+
// add offset 1023 to ensure positive
138+
// 0.6931471805599453 = Math.LN2;
139+
exp = ((Math.log(mix) / 0.6931471805599453) + 1023) | 0;
140+
141+
// frac => 53 bits
142+
// shift 52 - (exp - 1023) bits to make integer part exactly 53 bits,
143+
// then throw away trash less than decimal point
144+
frac = Math.floor(mix * Math.pow(2, 52 + 1023 - exp));
145+
146+
r8 = frac % 256;
147+
frac = (frac - r8) / 256; // frac is 45 bits
148+
149+
r7 = frac % 256;
150+
frac = (frac - r7) / 256; // frac is 37 bits
151+
152+
r6 = frac % 256;
153+
frac = (frac - r6) / 256; // frac is 29 bits
154+
155+
r5 = frac & 255;
156+
frac = frac >> 8; // frac is 21 bits
157+
158+
r4 = frac & 255;
159+
frac = frac >> 8; // frac is 13 bits
160+
161+
r3 = frac & 255;
162+
frac = frac >> 8; // frac is 5 bits
163+
164+
// take the rest 4 bits out of 5 from frac, and 4 bits from the exp
165+
r2 = (frac & 15) + ((exp & 15) << 4);
166+
167+
// take the rest 7 bits of exp, then add sign bit
168+
r1 = exp >> 4;
169+
sign && (r1 += 128);
170+
171+
rv.push(0xcb, r1, r2, r3, r4, r5, r6, r7, r8);
172+
}
173+
174+
return rv;
175+
}
176+
177+
function test4(input) {
178+
var rv = [], mix, sign, exp, frac, high, low;
179+
180+
for (var i = 0, l = input.length; i < l; i++) {
181+
mix = input[i];
182+
183+
sign = mix < 0;
184+
sign && (mix *= -1);
185+
186+
// exp => 11 bits
187+
// add offset 1023 to ensure positive
188+
// 0.6931471805599453 = Math.LN2;
189+
exp = ((Math.log(mix) / 0.6931471805599453) + 1023) | 0;
190+
191+
// frac => 53 bits
192+
// shift 52 - (exp - 1023) bits to make integer part exactly 53 bits,
193+
// then throw away trash less than decimal point
194+
frac = Math.floor(mix * Math.pow(2, 52 + 1023 - exp));
195+
196+
high = Math.floor(frac / 0x100000000) | exp << 20;
197+
low = frac & (0x100000000 - 1);
198+
199+
sign && (high += 0x80000000);
200+
201+
rv.push(0xcb, (high >> 24) & 0xff, (high >> 16) & 0xff,
202+
(high >> 8) & 0xff, high & 0xff,
203+
(low >> 24) & 0xff, (low >> 16) & 0xff,
204+
(low >> 8) & 0xff, low & 0xff);
205+
}
206+
207+
return rv;
208+
}
209+
function test5(input) {
210+
var rv = [], mix = 0, sign = false, exp = 0, frac = 0, high = 0, low = 0,
211+
LN2 = Math.LN2;
212+
213+
for (var i = 0, l = input.length; i < l; i++) {
214+
mix = input[i];
215+
216+
sign = mix < 0;
217+
sign && (mix *= -1);
218+
219+
// exp => 11 bits
220+
// add offset 1023 to ensure positive
221+
// 0.6931471805599453 = Math.LN2;
222+
exp = ((Math.log(mix) / LN2) + 1023) | 0;
223+
224+
// frac => 53 bits
225+
// shift 52 - (exp - 1023) bits to make integer part exactly 53 bits,
226+
// then throw away trash less than decimal point
227+
frac = Math.floor(mix * Math.pow(2, 52 + 1023 - exp));
228+
229+
// S+-Exp(11)--++-----------------Fraction(52bits)-----------------------+
230+
// || || |
231+
// v+----------++--------------------------------------------------------+
232+
// 00000000|00000000|00000000|00000000|00000000|00000000|00000000|00000000
233+
// 6 5 55 4 4 3 2 1 8 0
234+
// 3 6 21 8 0 2 4 6
235+
//
236+
// +----------high(32bits)-----------+ +----------low(32bits)------------+
237+
// | | | |
238+
// +---------------------------------+ +---------------------------------+
239+
// 3 2 21 1 8 0
240+
// 1 4 09 6
241+
low = frac & 0xffffffff;
242+
sign && (exp |= 0x800);
243+
high = ((frac / 0x100000000) & 0xfffff) | (exp << 20);
244+
245+
rv.push(0xcb, (high >> 24) & 0xff, (high >> 16) & 0xff,
246+
(high >> 8) & 0xff, high & 0xff,
247+
(low >> 24) & 0xff, (low >> 16) & 0xff,
248+
(low >> 8) & 0xff, low & 0xff);
249+
}
250+
251+
return rv;
252+
}
253+
254+
var t = new Date;
255+
var rv = test1(input);
256+
print('test1 took ' + (new Date - t) + ' ms, results : ' + rv.slice(0, 10) + ' ...');
257+
258+
var t = new Date;
259+
var rv = test2(input);
260+
print('test2 took ' + (new Date - t) + ' ms, results : ' + rv.slice(0, 10) + ' ...');
261+
262+
var t = new Date;
263+
var rv = test3(input);
264+
print('test3 took ' + (new Date - t) + ' ms, results : ' + rv.slice(0, 10) + ' ...');
265+
266+
var t = new Date;
267+
var rv = test4(input);
268+
print('test4 took ' + (new Date - t) + ' ms, results : ' + rv.slice(0, 10) + ' ...');
269+
270+
var t = new Date;
271+
var rv = test5(input);
272+
print('test5 took ' + (new Date - t) + ' ms, results : ' + rv.slice(0, 10) + ' ...');
273+
274+
};
275+
</script>

test/bench.htm

+9-23
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
<script src="../msgpack.js"></script>
55
<script src="uupaa.js"></script>
66
<script src="10000.js"></script>
7-
<!--
87
<script src="100000.js"></script>
9-
-->
108
<script>
119

1210

@@ -119,13 +117,6 @@
119117
}
120118
</script>
121119
</head><body>
122-
<h1>Benchmark</h1>
123-
<div>
124-
<input type="button" value="clear log" onclick="uu.log.clear()" />
125-
</div>
126-
127-
128-
<hr />
129120
<table>
130121
<tr>
131122
<td>Prepare Data</td>
@@ -134,33 +125,28 @@ <h1>Benchmark</h1>
134125
</tr>
135126
<tr>
136127
<td>
137-
<!--
138128
<input type="button" value="Load 100000" onclick="solid(solid100000, 100000)" />
139-
-->
140129
<input type="button" value="Load 10000" onclick="solid(solid10000, 10000)" />
141130
<input type="button" value="Load 10" onclick="load10()" />
142131
<br />
132+
<input type="button" id="Biggest" value="Create 100000" onclick="create(100000)" />
133+
<input type="button" value="Create 10000" onclick="create(10000)" />
134+
<input type="button" value="Create 10" onclick="create(10)" />
143135
</td>
144-
<td> -&gt; </td>
145136
<td>
146-
<input type="button" value="JSON.stringify + JSON.parse" onclick="test(1)" />
137+
-&gt;
147138
</td>
148-
</tr>
149-
<tr>
150-
<td>
151-
</td>
152-
<td> -&gt; </td>
153139
<td>
140+
<input type="button" value="JSON.stringify + JSON.parse" onclick="test(1)" />
141+
<br />
154142
<input type="button" value="msgpack.pack + msgpack.unpack" onclick="test(0)" />
155143
</td>
156144
</tr>
157145
</table>
158146
<textarea id="json" cols="40" rows="2"></textarea>
159-
<br />
160-
<input type="button" id="Biggest" value="Create 100000" onclick="create(100000)" />
161-
<input type="button" value="Create 10000" onclick="create(10000)" />
162-
<input type="button" value="Create 1000" onclick="create(1000)" />
163-
<input type="button" value="Create 10" onclick="create(10)" />
147+
<input type="button" value="clear log" onclick="uu.log.clear()" />
148+
149+
164150

165151

166152

0 commit comments

Comments
 (0)