From 2cac68467f6ed445add8ccd5d4f0781eea9cae58 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sun, 22 Sep 2019 13:16:38 +0200 Subject: [PATCH] Reduce the number of function calls in the `Dict` class The following changes were made: - Remove unnecessary `typeof` checks in the `get`/`getAsync` methods. - Reduce unnecessary code duplication in the `get`/`getAsync` methods. - Inline the `Ref` checks in the `get`/`getAsync`/`getArray` methods, since it helps avoid many unnecessary functions calls. I.e. this way it's possible to directly call `XRef.{fetch, fetchAsync)` only when necessary, rather than always having to call `XRef.{fetchIfRef, fetchIfRefAsync)`. This patch was tested using the PDF file from issue 2618, i.e. http://bugzilla-attachments.gnome.org/attachment.cgi?id=226471, using the following manifest file: ``` [ { "id": "issue2618", "file": "../web/pdfs/issue2618.pdf", "md5": "", "rounds": 250, "type": "eq" } ] ``` This 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 | 250 | 2821 | 2790 | -32 | -1.12 | faster Firefox | Page Request | 250 | 2 | 2 | 0 | 6.68 | Firefox | Rendering | 250 | 2820 | 2788 | -32 | -1.13 | faster ``` --- src/core/primitives.js | 62 +++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 37 deletions(-) diff --git a/src/core/primitives.js b/src/core/primitives.js index fe3c51e91928e..62a4f0e2c34fa 100644 --- a/src/core/primitives.js +++ b/src/core/primitives.js @@ -81,59 +81,47 @@ var Dict = (function DictClosure() { }, // automatically dereferences Ref objects - get: function Dict_get(key1, key2, key3) { - var value; - var xref = this.xref, suppressEncryption = this.suppressEncryption; - if (typeof (value = this._map[key1]) !== 'undefined' || - key1 in this._map || typeof key2 === 'undefined') { - return xref ? xref.fetchIfRef(value, suppressEncryption) : value; + get(key1, key2, key3) { + let value = this._map[key1]; + if (value === undefined && !(key1 in this._map) && key2 !== undefined) { + value = this._map[key2]; + if (value === undefined && !(key2 in this._map) && key3 !== undefined) { + value = this._map[key3]; + } } - if (typeof (value = this._map[key2]) !== 'undefined' || - key2 in this._map || typeof key3 === 'undefined') { - return xref ? xref.fetchIfRef(value, suppressEncryption) : value; + if (value instanceof Ref && this.xref) { + return this.xref.fetch(value, this.suppressEncryption); } - value = this._map[key3]; - return xref ? xref.fetchIfRef(value, suppressEncryption) : value; + return value; }, // Same as get(), but returns a promise and uses fetchIfRefAsync(). - getAsync: function Dict_getAsync(key1, key2, key3) { - var value; - var xref = this.xref, suppressEncryption = this.suppressEncryption; - if (typeof (value = this._map[key1]) !== 'undefined' || - key1 in this._map || typeof key2 === 'undefined') { - if (xref) { - return xref.fetchIfRefAsync(value, suppressEncryption); + async getAsync(key1, key2, key3) { + let value = this._map[key1]; + if (value === undefined && !(key1 in this._map) && key2 !== undefined) { + value = this._map[key2]; + if (value === undefined && !(key2 in this._map) && key3 !== undefined) { + value = this._map[key3]; } - return Promise.resolve(value); } - if (typeof (value = this._map[key2]) !== 'undefined' || - key2 in this._map || typeof key3 === 'undefined') { - if (xref) { - return xref.fetchIfRefAsync(value, suppressEncryption); - } - return Promise.resolve(value); + if (value instanceof Ref && this.xref) { + return this.xref.fetchAsync(value, this.suppressEncryption); } - value = this._map[key3]; - if (xref) { - return xref.fetchIfRefAsync(value, suppressEncryption); - } - return Promise.resolve(value); + return value; }, // Same as get(), but dereferences all elements if the result is an Array. - getArray: function Dict_getArray(key1, key2, key3) { - var value = this.get(key1, key2, key3); - var xref = this.xref, suppressEncryption = this.suppressEncryption; - if (!Array.isArray(value) || !xref) { + getArray(key1, key2, key3) { + let value = this.get(key1, key2, key3); + if (!Array.isArray(value) || !this.xref) { return value; } value = value.slice(); // Ensure that we don't modify the Dict data. - for (var i = 0, ii = value.length; i < ii; i++) { - if (!isRef(value[i])) { + for (let i = 0, ii = value.length; i < ii; i++) { + if (!(value[i] instanceof Ref)) { continue; } - value[i] = xref.fetch(value[i], suppressEncryption); + value[i] = this.xref.fetch(value[i], this.suppressEncryption); } return value; },