From 95fda4fcdcd9e131df823e3980bf3a019b1ad7b7 Mon Sep 17 00:00:00 2001 From: p01 Date: Wed, 14 May 2014 16:06:28 +0200 Subject: [PATCH 1/3] Optimized function.js / 2x Faster PDFFunction_constructPostScriptFromIR --- src/shared/function.js | 81 +++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 45 deletions(-) diff --git a/src/shared/function.js b/src/shared/function.js index 630b20356..b6e0f3a9c 100644 --- a/src/shared/function.js +++ b/src/shared/function.js @@ -385,66 +385,57 @@ var PDFFunction = (function PDFFunctionClosure() { var domain = IR[1]; var range = IR[2]; var code = IR[3]; - var numOutputs = range.length / 2; + var numOutputs = range.length >> 1; + var numInputs = domain.length >> 1; var evaluator = new PostScriptEvaluator(code); // Cache the values for a big speed up, the cache size is limited though // since the number of possible values can be huge from a PS function. - var cache = new FunctionCache(); + var cache = {}; + // The MAX_CACHE_SIZE is set to ~4x the maximum number of distinct values + // seen in our tests. + var MAX_CACHE_SIZE = 2048 * 4; + var cache_available = MAX_CACHE_SIZE; return function constructPostScriptFromIRResult(args) { - var initialStack = []; - for (var i = 0, ii = (domain.length / 2); i < ii; ++i) { - initialStack.push(args[i]); + var i, value; + var key = ''; + var input = new Array(numInputs); + for (i = 0; i < numInputs; i++) { + value = args[i]; + input[i] = value; + key += value + '_'; } - var key = initialStack.join('_'); - if (cache.has(key)) { - return cache.get(key); + var cachedValue = cache[key]; + if (cachedValue !== undefined) { + return cachedValue; } - var stack = evaluator.execute(initialStack); - var transformed = []; - for (i = numOutputs - 1; i >= 0; --i) { - var out = stack.pop(); - var rangeIndex = 2 * i; - if (out < range[rangeIndex]) { - out = range[rangeIndex]; - } else if (out > range[rangeIndex + 1]) { - out = range[rangeIndex + 1]; + var output = new Array(numOutputs); + var stack = evaluator.execute(input); + var stackIndex = stack.length - numOutputs; + for (i = 0; i < numOutputs; i++) { + value = stack[stackIndex + i]; + var bound = range[i * 2]; + if (value < bound) { + value = bound; + } else { + bound = range[i * 2 +1]; + if (value > bound) { + value = bound; + } } - transformed[i] = out; + output[i] = value; } - cache.set(key, transformed); - return transformed; + if (cache_available > 0) { + cache_available--; + cache[key] = output; + } + return output; }; } }; })(); -var FunctionCache = (function FunctionCacheClosure() { - // Of 10 PDF's with type4 functions the maxium number of distinct values seen - // was 256. This still may need some tweaking in the future though. - var MAX_CACHE_SIZE = 1024; - function FunctionCache() { - this.cache = {}; - this.total = 0; - } - FunctionCache.prototype = { - has: function FunctionCache_has(key) { - return key in this.cache; - }, - get: function FunctionCache_get(key) { - return this.cache[key]; - }, - set: function FunctionCache_set(key, value) { - if (this.total < MAX_CACHE_SIZE) { - this.cache[key] = value; - this.total++; - } - } - }; - return FunctionCache; -})(); - var PostScriptStack = (function PostScriptStackClosure() { var MAX_STACK_SIZE = 100; function PostScriptStack(initialStack) { From 8cfd024e484cc5d1b63bb76a6e7b319be3393ca4 Mon Sep 17 00:00:00 2001 From: p01 Date: Thu, 8 May 2014 17:31:11 +0200 Subject: [PATCH 2/3] Optimized colorspace.js AlternateCS_getRgbBuffer --- src/shared/colorspace.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/shared/colorspace.js b/src/shared/colorspace.js index aa49a2d1f..0d1b671bf 100644 --- a/src/shared/colorspace.js +++ b/src/shared/colorspace.js @@ -396,6 +396,7 @@ var AlternateCS = (function AlternateCSClosure() { getRgbBuffer: function AlternateCS_getRgbBuffer(src, srcOffset, count, dest, destOffset, bits, alpha01) { + var tinted; var tintFn = this.tintFn; var base = this.base; var scale = 1 / ((1 << bits) - 1); @@ -409,16 +410,22 @@ var AlternateCS = (function AlternateCSClosure() { var scaled = new Float32Array(numComps); var i, j; - for (i = 0; i < count; i++) { - for (j = 0; j < numComps; j++) { - scaled[j] = src[srcOffset++] * scale; - } - var tinted = tintFn(scaled); - if (usesZeroToOneRange) { + if (usesZeroToOneRange) { + for (i = 0; i < count; i++) { + for (j = 0; j < numComps; j++) { + scaled[j] = src[srcOffset++] * scale; + } + tinted = tintFn(scaled); for (j = 0; j < baseNumComps; j++) { baseBuf[pos++] = tinted[j] * 255; } - } else { + } + } else { + for (i = 0; i < count; i++) { + for (j = 0; j < numComps; j++) { + scaled[j] = src[srcOffset++] * scale; + } + tinted = tintFn(scaled); base.getRgbItem(tinted, 0, baseBuf, pos); pos += baseNumComps; } From 330b99f428bd8cfc8423fd307a1d65ad086d9392 Mon Sep 17 00:00:00 2001 From: p01 Date: Tue, 6 May 2014 16:45:49 +0200 Subject: [PATCH 3/3] Optimized stream.js / 9-10x faster DecodeStream_ensureBuffer --- src/core/stream.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/stream.js b/src/core/stream.js index abd9e81ed..a7d5d3456 100644 --- a/src/core/stream.js +++ b/src/core/stream.js @@ -144,8 +144,8 @@ var DecodeStream = (function DecodeStreamClosure() { size *= 2; } var buffer2 = new Uint8Array(size); - for (var i = 0; i < current; ++i) { - buffer2[i] = buffer[i]; + if (buffer) { + buffer2.set(buffer); } return (this.buffer = buffer2); },