From 7728a6630c63492ed56f2adb65b919f689522286 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Fri, 16 Aug 2019 10:20:43 +0200 Subject: [PATCH 1/2] Inline the `isString` check in the `Parser.getObj` method For very large and complex PDF files this will help performance *slightly*, since `Parser.getObj` is called *a lot* during parsing in the worker. This patch was tested using the PDF file from issue 2618, i.e. http://bugzilla-attachments.gnome.org/attachment.cgi?id=226471, with the following manifest file: ``` [ { "id": "issue2618", "file": "../web/pdfs/issue2618.pdf", "md5": "", "rounds": 200, "type": "eq" } ] ``` which gave the following results when comparing this patch against the `master` branch: ``` -- Grouped By browser, stat -- browser | stat | Count | Baseline(ms) | Current(ms) | +/- | % | Result(P<.05) ------- | ------------ | ----- | ------------ | ----------- | --- | ----- | ------------- Firefox | Overall | 200 | 2847 | 2830 | -17 | -0.60 | faster Firefox | Page Request | 200 | 2 | 2 | 0 | -7.14 | Firefox | Rendering | 200 | 2844 | 2827 | -17 | -0.60 | faster ``` --- src/core/parser.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/core/parser.js b/src/core/parser.js index db50e06f8..8c895136e 100644 --- a/src/core/parser.js +++ b/src/core/parser.js @@ -19,8 +19,7 @@ import { PredictorStream, RunLengthStream } from './stream'; import { - assert, bytesToString, FormatError, info, isNum, isSpace, isString, - StreamType, warn + assert, bytesToString, FormatError, info, isNum, isSpace, StreamType, warn } from '../shared/util'; import { Cmd, Dict, EOF, isCmd, isDict, isEOF, isName, Name, Ref @@ -158,7 +157,7 @@ class Parser { return num; } - if (isString(buf1)) { // string + if (typeof buf1 === 'string') { let str = buf1; if (cipherTransform) { str = cipherTransform.decryptString(str); From 40d3916f3110343e1b9db67455e28d49c19856f5 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Fri, 16 Aug 2019 13:47:12 +0200 Subject: [PATCH 2/2] Reduce the number of temporary variables in the `Parser.getObj` method This avoids allocating approximately 1.7 million short-lived variables when loading the PDF file from issue 2618, i.e. http://bugzilla-attachments.gnome.org/attachment.cgi?id=226471, in the default viewer. --- src/core/parser.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/core/parser.js b/src/core/parser.js index 8c895136e..176884296 100644 --- a/src/core/parser.js +++ b/src/core/parser.js @@ -89,7 +89,7 @@ class Parser { } } - getObj(cipherTransform) { + getObj(cipherTransform = null) { const buf1 = this.buf1; this.shift(); @@ -147,22 +147,20 @@ class Parser { } if (Number.isInteger(buf1)) { // indirect reference or integer - const num = buf1; if (Number.isInteger(this.buf1) && isCmd(this.buf2, 'R')) { - const ref = Ref.get(num, this.buf1); + const ref = Ref.get(buf1, this.buf1); this.shift(); this.shift(); return ref; } - return num; + return buf1; } if (typeof buf1 === 'string') { - let str = buf1; if (cipherTransform) { - str = cipherTransform.decryptString(str); + return cipherTransform.decryptString(buf1); } - return str; + return buf1; } // simple object