Skip to content

Commit

Permalink
Reduce the number of function calls in the Dict class
Browse files Browse the repository at this point in the history
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
```
  • Loading branch information
Snuffleupagus committed Sep 24, 2019
1 parent 44f4cd5 commit 2cac684
Showing 1 changed file with 25 additions and 37 deletions.
62 changes: 25 additions & 37 deletions src/core/primitives.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
},
Expand Down

0 comments on commit 2cac684

Please sign in to comment.