From 00ae70e9dd5c30b2cdd1bea305244782adae4f5b Mon Sep 17 00:00:00 2001 From: Arjun Barrett Date: Thu, 11 Feb 2021 12:23:33 -0800 Subject: [PATCH] Optimize loops for V8 Smi --- adler32.flow.js | 6 ++--- adler32.js | 6 ++--- bits/40_adler.js | 6 ++--- ctest/adler32.js | 6 ++--- perf/bstr.js | 18 +++++++++++++- perf/utf8.js | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 92 insertions(+), 13 deletions(-) diff --git a/adler32.flow.js b/adler32.flow.js index 7bc16c0..2cd9017 100644 --- a/adler32.flow.js +++ b/adler32.flow.js @@ -36,7 +36,7 @@ function adler32_bstr(bstr/*:string*/, seed/*:?ADLER32Type*/)/*:ADLER32Type*/ { var a = 1, b = 0, L = bstr.length, M = 0; if(typeof seed === 'number') { a = seed & 0xFFFF; b = seed >>> 16; } for(var i = 0; i < L;) { - M = Math.min(L-i, 3850)+i; + M = Math.min(L-i, 2654)+i; for(;i>> 16) & 0xFFFF; } for(var i = 0; i < L;) { - M = Math.min(L-i, 3850)+i; + M = Math.min(L-i, 2654)+i; for(;i>> 16; } for(var i = 0; i < L;) { - M = Math.min(L-i, 3850); + M = Math.min(L-i, 2918); while(M>0) { c = str.charCodeAt(i++); if(c < 0x80) { a += c; } diff --git a/adler32.js b/adler32.js index ad6bfb7..4a29ac3 100644 --- a/adler32.js +++ b/adler32.js @@ -28,7 +28,7 @@ function adler32_bstr(bstr, seed) { var a = 1, b = 0, L = bstr.length, M = 0; if(typeof seed === 'number') { a = seed & 0xFFFF; b = seed >>> 16; } for(var i = 0; i < L;) { - M = Math.min(L-i, 3850)+i; + M = Math.min(L-i, 2654)+i; for(;i>> 16) & 0xFFFF; } for(var i = 0; i < L;) { - M = Math.min(L-i, 3850)+i; + M = Math.min(L-i, 2654)+i; for(;i>> 16; } for(var i = 0; i < L;) { - M = Math.min(L-i, 3850); + M = Math.min(L-i, 2918); while(M>0) { c = str.charCodeAt(i++); if(c < 0x80) { a += c; } diff --git a/bits/40_adler.js b/bits/40_adler.js index 6b101e1..c990207 100644 --- a/bits/40_adler.js +++ b/bits/40_adler.js @@ -4,7 +4,7 @@ function adler32_bstr(bstr/*:string*/, seed/*:?ADLER32Type*/)/*:ADLER32Type*/ { var a = 1, b = 0, L = bstr.length, M = 0; if(typeof seed === 'number') { a = seed & 0xFFFF; b = seed >>> 16; } for(var i = 0; i < L;) { - M = Math.min(L-i, 3850)+i; + M = Math.min(L-i, 2654)+i; for(;i>> 16) & 0xFFFF; } for(var i = 0; i < L;) { - M = Math.min(L-i, 3850)+i; + M = Math.min(L-i, 2654)+i; for(;i>> 16; } for(var i = 0; i < L;) { - M = Math.min(L-i, 3850); + M = Math.min(L-i, 2918); while(M>0) { c = str.charCodeAt(i++); if(c < 0x80) { a += c; } diff --git a/ctest/adler32.js b/ctest/adler32.js index ad6bfb7..4a29ac3 100644 --- a/ctest/adler32.js +++ b/ctest/adler32.js @@ -28,7 +28,7 @@ function adler32_bstr(bstr, seed) { var a = 1, b = 0, L = bstr.length, M = 0; if(typeof seed === 'number') { a = seed & 0xFFFF; b = seed >>> 16; } for(var i = 0; i < L;) { - M = Math.min(L-i, 3850)+i; + M = Math.min(L-i, 2654)+i; for(;i>> 16) & 0xFFFF; } for(var i = 0; i < L;) { - M = Math.min(L-i, 3850)+i; + M = Math.min(L-i, 2654)+i; for(;i>> 16; } for(var i = 0; i < L;) { - M = Math.min(L-i, 3850); + M = Math.min(L-i, 2918); while(M>0) { c = str.charCodeAt(i++); if(c < 0x80) { a += c; } diff --git a/perf/bstr.js b/perf/bstr.js index e1319b6..acb6b25 100644 --- a/perf/bstr.js +++ b/perf/bstr.js @@ -15,7 +15,7 @@ function sheetjs1(bstr) { function sheetjs2(bstr) { var a = 1, b = 0, L = bstr.length, M = 0; for(var i = 0; i < L;) { - M = Math.min(L-i, 3850)+i; + M = Math.min(L-i, 2654)+i; for(;i>>16)+(a&65535)) + b = (15*(b>>>16)+(b&65535)) + } + return ((b%65521) << 16) | (a%65521); +} + +function sheetjs4(bstr) { var a = 1, b = 0, L = bstr.length, M = 0; for(var i = 0; i < L;) { M = Math.min(L-i, 5552); @@ -58,11 +72,13 @@ for(var i = 6; i != 14; ++i) { assert.equal(res, sheetjs1(foobar)); assert.equal(res, sheetjs2(foobar)); assert.equal(res, sheetjs3(foobar)); + assert.equal(res, sheetjs4(foobar)); var suite = new BM('binary string (' + foobar.length + ')'); if(i<3) suite.add('sheetjs 1', function() { for(var j = 0; j != m; ++j) sheetjs1(foobar); }); suite.add('sheetjs 2', function() { for(var j = 0; j != m; ++j) sheetjs2(foobar); }); suite.add('sheetjs 3', function() { for(var j = 0; j != m; ++j) sheetjs3(foobar); }); + suite.add('sheetjs 4', function() { for(var j = 0; j != m; ++j) sheetjs4(foobar); }); suite.add('last vers', function() { for(var j = 0; j != m; ++j) old(foobar); }); suite.add('current v', function() { for(var j = 0; j != m; ++j) cur(foobar); }); suite.run(); diff --git a/perf/utf8.js b/perf/utf8.js index 5f08191..066d9f8 100644 --- a/perf/utf8.js +++ b/perf/utf8.js @@ -17,6 +17,64 @@ function sheetjs1(utf8) { } function sheetjs2(utf8) { + var a = 1, b = 0, L = utf8.length, M, c, d; + for(var i = 0; i < L;) { + M = Math.min(L-i, 2654); + while(M>0) { + c = utf8.charCodeAt(i++); + if(c < 0x80) { + a += c; b += a; --M; + } else if(c < 0x800) { + a += 192|((c>>6)&31); b += a; --M; + a += 128|(c&63); b += a; --M; + } else if(c >= 0xD800 && c < 0xE000) { + c = (c&1023)+64; d = utf8.charCodeAt(i++) & 1023; + a += 240|((c>>8)&7); b += a; --M; + a += 128|((c>>2)&63); b += a; --M; + a += 128|((d>>6)&15)|((c&3)<<4); b += a; --M; + a += 128|(d&63); b += a; --M; + } else { + a += 224|((c>>12)&15); b += a; --M; + a += 128|((c>>6)&63); b += a; --M; + a += 128|(c&63); b += a; --M; + } + } + a %= 65521; + b %= 65521; + } + return (b << 16) | a; +} + +function sheetjs3(utf8) { + var a = 1, b = 0, L = utf8.length, M, c, d; + for(var i = 0; i < L;) { + M = Math.min(L-i, 2918); + while(M>0) { + c = utf8.charCodeAt(i++); + if(c < 0x80) { + a += c; b += a; --M; + } else if(c < 0x800) { + a += 192|((c>>6)&31); b += a; --M; + a += 128|(c&63); b += a; --M; + } else if(c >= 0xD800 && c < 0xE000) { + c = (c&1023)+64; d = utf8.charCodeAt(i++) & 1023; + a += 240|((c>>8)&7); b += a; --M; + a += 128|((c>>2)&63); b += a; --M; + a += 128|((d>>6)&15)|((c&3)<<4); b += a; --M; + a += 128|(d&63); b += a; --M; + } else { + a += 224|((c>>12)&15); b += a; --M; + a += 128|((c>>6)&63); b += a; --M; + a += 128|(c&63); b += a; --M; + } + } + a %= 65521; + b %= 65521; + } + return (b << 16) | a; +} + +function sheetjs4(utf8) { var a = 1, b = 0, L = utf8.length, M, c, d; for(var i = 0; i < L;) { M = Math.min(L-i, 3850); @@ -53,11 +111,16 @@ var res = old(foobar); assert.equal(res, cur(foobar)); assert.equal(res, sheetjs1(foobar)); assert.equal(res, sheetjs2(foobar)); +assert.equal(res, sheetjs3(foobar)); +assert.equal(res, sheetjs4(foobar)); + var BM = require('./bm'); var suite = new BM('unicode string'); suite.add('sheetjs 1', function() { for(var j = 0; j != 1000; ++j) sheetjs1(foobar); }); suite.add('sheetjs 2', function() { for(var j = 0; j != 1000; ++j) sheetjs2(foobar); }); +suite.add('sheetjs 3', function() { for(var j = 0; j != 1000; ++j) sheetjs3(foobar); }); +suite.add('sheetjs 4', function() { for(var j = 0; j != 1000; ++j) sheetjs4(foobar); }); suite.add('last vers', function() { for(var j = 0; j != 1000; ++j) old(foobar); }); suite.add('current v', function() { for(var j = 0; j != 1000; ++j) cur(foobar); }); suite.run();