From b0a8c0fa400d6e236c16f0c733eb0324d38e430f Mon Sep 17 00:00:00 2001 From: Rob Wu Date: Sat, 8 Aug 2015 01:16:05 +0200 Subject: [PATCH] cmaps: Use cmap.forEach instead of Array.forEach CMaps may be sparse. Array.prototype.forEach is terribly slow in Chrome (and also in Firefox) when the sparse array contains a key with a high value. E.g. console.time('forEach sparse') var a = []; a[0xFFFFFF] = 1; a.forEach(function(){}); console.timeEnd('forEach sparse'); // Chrome: 2890ms // Firefox: 1345ms Switching to CMap.prototype.forEach, which is optimized for such scenarios fixes the problem. --- src/core/evaluator.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/evaluator.js b/src/core/evaluator.js index ed137f805..9eb9c631a 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -1370,11 +1370,11 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { if (cmap instanceof IdentityCMap) { return new IdentityToUnicodeMap(0, 0xFFFF); } - cmap = cmap.getMap(); + var map = []; // Convert UTF-16BE // NOTE: cmap can be a sparse array, so use forEach instead of for(;;) // to iterate over all keys. - cmap.forEach(function(token, i) { + cmap.forEach(function(charCode, token) { var str = []; for (var k = 0; k < token.length; k += 2) { var w1 = (token.charCodeAt(k) << 8) | token.charCodeAt(k + 1); @@ -1386,9 +1386,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var w2 = (token.charCodeAt(k) << 8) | token.charCodeAt(k + 1); str.push(((w1 & 0x3ff) << 10) + (w2 & 0x3ff) + 0x10000); } - cmap[i] = String.fromCharCode.apply(String, str); + map[charCode] = String.fromCharCode.apply(String, str); }); - return new ToUnicodeMap(cmap); + return new ToUnicodeMap(map); } return null; },