internal-typed-array-vs-vars-sha1
JavaScript performance comparison
Info
This test compares using several local variables vs a Uint32Array for the words (32 bit uints) used internally in the sha1 algorithm. I find it very interesting that the behavior varies a lot by browser.
Preparation code
<script>
function stringToBuffer(string) {
string = unescape(encodeURIComponent(string));
var length = string.length;
var buf = new Uint8Array(length);
for (var i = 0; i < length; i++) {
buf[i] = string.charCodeAt(i);
}
return buf;
};
// input is a Uint8Array bitstream of the data
function sha1_array(input) {
var H = new Uint32Array([0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0]),
m = [],
l = input.length * 8,
w = [];
for (var i = 0, b = 0, end=l/8; i < end; i++, b += 8) {
m[b >>> 5] |= input[i] << (24 - b % 32);
}
m[l >> 5] |= 0x80 << (24 - l % 32);
m[((l + 64 >>> 9) << 4) + 15] = l;
for (var i = 0, end = m.length; i < end; i += 16) {
var a = H[0], b = H[1], c = H[2], d = H[3], e = H[4];
for (var j = 0; j < 80; j++) {
if (j < 16) {
w[j] = m[i + j];
}
else {
var n = w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16];
w[j] = (n << 1) | (n >>> 31);
}
var t = ((H[0] << 5) | (H[0] >>> 27)) + H[4] + (w[j] >>> 0) + (
j < 20 ? (H[1] & H[2] | ~H[1] & H[3]) + 0x5a827999 :
j < 40 ? (H[1] ^ H[2] ^ H[3]) + 0x6ed9eba1 :
j < 60 ? (H[1] & H[2] | H[1] & H[3] | H[2] & H[3]) - 0x70e44324 :
(H[1] ^ H[2] ^ H[3]) - 0x359d3e2a);
H[4] = H[3];
H[3] = H[2];
H[2] = (H[1] << 30) | (H[1] >>> 2);
H[1] = H[0];
H[0] = t;
}
H[0] += a;
H[1] += b;
H[2] += c;
H[3] += d;
H[4] += e;
}
return new Uint8Array(H.buffer);
}
// input is a Uint8Array bitstream of the data
function sha1_vars(input){
var H0 = 0x67452301,
H1 = 0xefcdab89,
H2 = 0x98badcfe,
H3 = 0x10325476,
H4 = 0xc3d2e1f0,
m = [],
l = input.length * 8,
w = [];
for (var i = 0, b = 0; i < l/8; i++, b += 8) m[b >>> 5] |= input[i] << (24 - b % 32);
m[l >> 5] |= 0x80 << (24 - l % 32);
m[((l + 64 >>> 9) << 4) + 15] = l;
for (var i = 0; i < m.length; i += 16) {
var a = H0, b = H1, c = H2, d = H3, e = H4;
for (var j = 0; j < 80; j++) {
if (j < 16)
w[j] = m[i + j];
else {
var n = w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16];
w[j] = (n << 1) | (n >>> 31);
}
var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + (
j < 20 ? (H1 & H2 | ~H1 & H3) + 0x5a827999 :
j < 40 ? (H1 ^ H2 ^ H3) + 0x6ed9eba1 :
j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 0x70e44324 :
(H1 ^ H2 ^ H3) - 0x359d3e2a);
H4 = H3;
H3 = H2;
H2 = (H1 << 30) | (H1 >>> 2);
H1 = H0;
H0 = t;
}
H0 += a;
H1 += b;
H2 += c;
H3 += d;
H4 += e;
}
var H = new Uint32Array([H0, H1, H2, H3, H4]);
return new Uint8Array(H.buffer);
}
// input is a Uint8Array bitstream of the data
function sha1_vars_return_array(input){
var H0 = 0x67452301,
H1 = 0xefcdab89,
H2 = 0x98badcfe,
H3 = 0x10325476,
H4 = 0xc3d2e1f0,
m = [],
l = input.length * 8,
w = [];
for (var i = 0, b = 0; i < l/8; i++, b += 8) m[b >>> 5] |= input[i] << (24 - b % 32);
m[l >> 5] |= 0x80 << (24 - l % 32);
m[((l + 64 >>> 9) << 4) + 15] = l;
for (var i = 0; i < m.length; i += 16) {
var a = H0, b = H1, c = H2, d = H3, e = H4;
for (var j = 0; j < 80; j++) {
if (j < 16)
w[j] = m[i + j];
else {
var n = w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16];
w[j] = (n << 1) | (n >>> 31);
}
var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + (
j < 20 ? (H1 & H2 | ~H1 & H3) + 0x5a827999 :
j < 40 ? (H1 ^ H2 ^ H3) + 0x6ed9eba1 :
j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 0x70e44324 :
(H1 ^ H2 ^ H3) - 0x359d3e2a);
H4 = H3;
H3 = H2;
H2 = (H1 << 30) | (H1 >>> 2);
H1 = H0;
H0 = t;
}
H0 += a;
H1 += b;
H2 += c;
H3 += d;
H4 += e;
}
return [H0, H1, H2, H3, H4];
}
</script>
<script>
Benchmark.prototype.setup = function() {
var inputs = [
stringToBuffer("Hello World"),
stringToBuffer("Hello World, This is a much longer message to test multiple chunks")
]
};
</script>
Test runner
Warning! For accurate results, please disable Firebug before running the tests. (Why?)
Java applet disabled.
| Test | Ops/sec | |
|---|---|---|
internal-vars |
|
pending… |
inner-typed |
|
pending… |
_return_array |
|
pending… |
Compare results of other browsers
Revisions
You can edit these tests or add even more tests to this page by appending /edit to the URL. Here’s a list of current revisions for this page:
- Revision 1: published by Tim Caswell
- Revision 2: published
- Revision 3: published
- Revision 4: published
0 comments