Improved performance for our adler32 implementation
Jim committed
Jul 16, 2015 at 08:29 UTC
57e9e5bf23ba0d498ffaedf8f8df37ad2968d4dd
2 files changed
+65
-7
src/shared/utils/__tests__/adler32-test.js
new
+41
@@ -0,0 +1,41 @@
1
+/**
2
+ * Copyright 2014-2015, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ * @emails react-core
10
+ */
11
+
12
+'use strict';
13
+
14
+var adler32 = require('adler32');
15
+
16
+describe('shallowEqual', function() {
17
+ it('generates differing checksums', function() {
18
+ expect(adler32('foo')).not.toBe(adler32('bar'));
19
+ });
20
+
21
+ it('generates consistent checksums', function() {
22
+ expect(adler32('linux')).toBe(adler32('linux'));
23
+ });
24
+
25
+ it('is case sensitive', function() {
26
+ expect(adler32('a')).not.toBe(adler32('A'));
27
+ });
28
+
29
+ it('doesn\'t barf on large inputs', function() {
30
+ var str = '';
31
+ for (var i = 0; i < 100000; i++) {
32
+ str = str + 'This will be repeated to be very large indeed. ';
33
+ }
34
+ expect(adler32(str)).toBe(692898118);
35
+ });
36
+
37
+ it('doesn\'t barf on international inputs', function() {
38
+ var str = 'Linux 是一個真棒操作系統!';
39
+ expect(adler32(str)).toBe(-1183804097);
40
+ });
41
+});
src/shared/utils/adler32.js
+24
-7
@@ -13,17 +13,34 @@
13
14
var MOD = 65521;
15
16
-// This is a clean-room implementation of adler32 designed for detecting
17
-// if markup is not what we expect it to be. It does not need to be
18
-// cryptographically strong, only reasonably good at detecting if markup
19
-// generated on the server is different than that on the client.
16
+// adler32 is not cryptographically strong, and is only used to sanity check that
17
+// markup generated on the server matches the markup generated on the client.
18
+// This implementation (a modified version of the SheetJS version) has been optimized
19
+// for our use case, at the expense of conforming to the adler32 specification
20
+// for non-ascii inputs.
21
function adler32(data) {
22
var a = 1;
23
var b = 0;
23
- for (var i = 0; i < data.length; i++) {
24
- a = (a + data.charCodeAt(i)) % MOD;
25
- b = (b + a) % MOD;
24
+ var i = 0;
25
+ var l = data.length;
26
+ var m = l & ~0x3;
27
+ while (i < m) {
28
+ for (; i < Math.min(i + 4096, m); i += 4) {
29
+ b += (
30
+ (a += data.charCodeAt(i)) +
31
+ (a += data.charCodeAt(i + 1)) +
32
+ (a += data.charCodeAt(i + 2)) +
33
+ (a += data.charCodeAt(i + 3))
34
+ );
35
+ }
36
+ a %= MOD;
37
+ b %= MOD;
38
}
39
+ for (; i < l; i++) {
40
+ b += (a += data.charCodeAt(i));
41
+ }
42
+ a %= MOD;
43
+ b %= MOD;
44
return a | (b << 16);
45
}
46