@samitouri / QOS-React-2 / commits / 57e9e5bf23

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