[Pkg-javascript-commits] [pdf.js] 175/246: Avoid unnecessary array allocations in EvaluatorPreprocessor_read().
David Prévot
taffit at moszumanska.debian.org
Sun Sep 7 15:36:38 UTC 2014
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository pdf.js.
commit 7cbd057deb503ed30b708fea465018352d5006a7
Author: Nicholas Nethercote <nnethercote at mozilla.com>
Date: Sun Aug 10 17:23:23 2014 -0700
Avoid unnecessary array allocations in EvaluatorPreprocessor_read().
EvaluatorPreprocessor_read() is called in two cases. For the normal
layer, the args array it produces is used beyond the bounds of the loop
in which EvaluatorPreprocessor_read() is called.
But for the text layer, the args array is used in a very short-term
fashion. This change reworks things so that a single array is repeatedly
used for the text layer. This reduces total JS allocations for the
Spoorkaart map by 11%, and has similar effects on many other PDFs.
---
src/core/evaluator.js | 52 ++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 43 insertions(+), 9 deletions(-)
diff --git a/src/core/evaluator.js b/src/core/evaluator.js
index 603f248..bdfbd8f 100644
--- a/src/core/evaluator.js
+++ b/src/core/evaluator.js
@@ -642,8 +642,15 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
return new Promise(function next(resolve, reject) {
timeSlotManager.reset();
var stop, operation = {}, i, ii, cs;
- while (!(stop = timeSlotManager.check()) &&
- preprocessor.read(operation)) {
+ while (!(stop = timeSlotManager.check())) {
+ // The arguments parsed by read() are used beyond this loop, so we
+ // cannot reuse the same array on each iteration. Therefore we pass
+ // in |null| as the initial value (see the comment on
+ // EvaluatorPreprocessor_read() for why).
+ operation.args = null;
+ if (!(preprocessor.read(operation))) {
+ break;
+ }
var args = operation.args;
var fn = operation.fn;
@@ -1037,12 +1044,20 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
return new Promise(function next(resolve, reject) {
timeSlotManager.reset();
- var stop, operation = {};
- while (!(stop = timeSlotManager.check()) &&
- (preprocessor.read(operation))) {
+ var stop, operation = {}, args = [];
+ while (!(stop = timeSlotManager.check())) {
+ // The arguments parsed by read() are not used beyond this loop, so
+ // we can reuse the same array on every iteration, thus avoiding
+ // unnecessary allocations.
+ args.length = 0;
+ operation.args = args;
+ if (!(preprocessor.read(operation))) {
+ break;
+ }
textState = stateManager.state;
var fn = operation.fn;
- var args = operation.args;
+ args = operation.args;
+
switch (fn | 0) {
case OPS.setFont:
textState.fontSize = args[1];
@@ -2112,10 +2127,29 @@ var EvaluatorPreprocessor = (function EvaluatorPreprocessorClosure() {
return this.stateManager.stateStack.length;
},
+ // |operation| is an object with two fields:
+ //
+ // - |fn| is an out param.
+ //
+ // - |args| is an inout param. On entry, it should have one of two values.
+ //
+ // - An empty array. This indicates that the caller is providing the
+ // array in which the args will be stored in. The caller should use
+ // this value if it can reuse a single array for each call to read().
+ //
+ // - |null|. This indicates that the caller needs this function to create
+ // the array in which any args are stored in. If there are zero args,
+ // this function will leave |operation.args| as |null| (thus avoiding
+ // allocations that would occur if we used an empty array to represent
+ // zero arguments). Otherwise, it will replace |null| with a new array
+ // containing the arguments. The caller should use this value if it
+ // cannot reuse an array for each call to read().
+ //
+ // These two modes are present because this function is very hot and so
+ // avoiding allocations where possible is worthwhile.
+ //
read: function EvaluatorPreprocessor_read(operation) {
- // We use an array to represent args, except we use |null| to represent
- // no args because it's more compact than an empty array.
- var args = null;
+ var args = operation.args;
while (true) {
var obj = this.parser.getObj();
if (isCmd(obj)) {
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/pdf.js.git
More information about the Pkg-javascript-commits
mailing list