From ffae848f4ea24c58f45ed14102a2670627f49ca4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 13 Aug 2014 23:25:45 -0700 Subject: [PATCH] Reduce ASCII checks in makeInlineImage(). makeInlineImage() has a "are the next five chars ASCII?" check which is run after an "EI" sequence has been found. This check involves the creation of a new object because peekBytes() calls subarray(). Unfortunately, the check is currently run on whitespace chars even when an "EI" sequence has not yet been found, i.e. when it's not needed. For the PDF in #2618, there are over 820,000 such checks. This change reworks the relevant loop so that the check is only done once an "EI" sequence has been seen. This reduces the number of checks to 157,000, and speeds up rendering by somewhere between 2% and 7% (the measurements are noisy). --- src/core/parser.js | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/core/parser.js b/src/core/parser.js index ec0666ac5..1f78d224a 100644 --- a/src/core/parser.js +++ b/src/core/parser.js @@ -18,7 +18,7 @@ FlateStream, isArray, isCmd, isDict, isInt, isName, isNum, isRef, isString, Jbig2Stream, JpegStream, JpxStream, LZWStream, Name, NullStream, PredictorStream, Ref, RunLengthStream, warn, info, - StreamType, MissingDataException */ + StreamType, MissingDataException, assert */ 'use strict'; @@ -152,32 +152,33 @@ var Parser = (function ParserClosure() { // searching for the /EI\s/ var state = 0, ch, i, ii; - while (state !== 4 && (ch = stream.getByte()) !== -1) { - switch (ch | 0) { - case 0x20: - case 0x0D: - case 0x0A: - // let's check next five bytes to be ASCII... just be sure - var followingBytes = stream.peekBytes(5); - for (i = 0, ii = followingBytes.length; i < ii; i++) { + var E = 0x45, I = 0x49, SPACE = 0x20, NL = 0xA, CR = 0xD; + while ((ch = stream.getByte()) !== -1) { + if (state === 0) { + state = (ch === E) ? 1 : 0; + } else if (state === 1) { + state = (ch === I) ? 2 : 0; + } else { + assert(state === 2); + if (ch === SPACE || ch === NL || ch === CR) { + // Let's check the next five bytes are ASCII... just be sure. + var n = 5; + var followingBytes = stream.peekBytes(n); + for (i = 0; i < n; i++) { ch = followingBytes[i]; - if (ch !== 0x0A && ch !== 0x0D && (ch < 0x20 || ch > 0x7F)) { - // not a LF, CR, SPACE or any visible ASCII character + if (ch !== NL && ch !== CR && (ch < SPACE || ch > 0x7F)) { + // Not a LF, CR, SPACE or any visible ASCII character, i.e. + // it's binary stuff. Resetting the state. state = 0; - break; // some binary stuff found, resetting the state + break; } } - state = (state === 3 ? 4 : 0); - break; - case 0x45: - state = 2; - break; - case 0x49: - state = (state === 2 ? 3 : 0); - break; - default: + if (state === 2) { + break; // finished! + } + } else { state = 0; - break; + } } }