Skip to content

Commit 2e07715

Browse files
committed
Reduce function creation when using Map.prototype.getOrInsertComputed()
With the exception of the first invocation the callback function is unused, which means that a lot of pointless functions may be created. To avoid this we introduce helper functions for simple cases, such as creating `Map`s and `Objects`s.
1 parent c2f5e19 commit 2e07715

File tree

10 files changed

+40
-19
lines changed

10 files changed

+40
-19
lines changed

src/core/xfa/fonts.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
* limitations under the License.
1414
*/
1515

16+
import { makeObj, warn } from "../../shared/util.js";
1617
import { $globalData } from "./symbol_utils.js";
1718
import { stripQuotes } from "./utils.js";
18-
import { warn } from "../../shared/util.js";
1919

2020
class FontFinder {
2121
constructor(pdfFonts) {
@@ -48,9 +48,7 @@ class FontFinder {
4848
addPdfFont(pdfFont) {
4949
const cssFontInfo = pdfFont.cssFontInfo;
5050
const name = cssFontInfo.fontFamily;
51-
const font = this.fonts.getOrInsertComputed(name, () =>
52-
Object.create(null)
53-
);
51+
const font = this.fonts.getOrInsertComputed(name, makeObj);
5452
this.defaultFont ??= font;
5553

5654
let property = "";

src/core/xfa/som.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
$getChildrenByName,
2020
$getParent,
2121
} from "./symbol_utils.js";
22-
import { warn } from "../../shared/util.js";
22+
import { makeMap, warn } from "../../shared/util.js";
2323

2424
const namePattern = /^[^.[]+/;
2525
const indexPattern = /^[^\]]+/;
@@ -193,7 +193,7 @@ function searchNode(
193193
let children, cached;
194194

195195
if (useCache) {
196-
cached = somCache.getOrInsertComputed(node, () => new Map());
196+
cached = somCache.getOrInsertComputed(node, makeMap);
197197
children = cached.get(cacheName);
198198
}
199199

src/display/annotation_storage.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* limitations under the License.
1414
*/
1515

16-
import { shadow, unreachable } from "../shared/util.js";
16+
import { makeMap, shadow, unreachable } from "../shared/util.js";
1717
import { AnnotationEditor } from "./editor/editor.js";
1818
import { MurmurHash3_64 } from "../shared/murmurhash3.js";
1919

@@ -260,7 +260,7 @@ class AnnotationStorage {
260260
if (key === "type") {
261261
continue;
262262
}
263-
const counters = map.getOrInsertComputed(key, () => new Map());
263+
const counters = map.getOrInsertComputed(key, makeMap);
264264
counters.set(val, (counters.get(val) ?? 0) + 1);
265265
}
266266
}

src/display/api.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
getVerbosityLevel,
2626
info,
2727
isNodeJS,
28+
makeObj,
2829
MathClamp,
2930
RenderingIntentFlag,
3031
setVerbosityLevel,
@@ -1502,8 +1503,9 @@ class PDFPageProxy {
15021503
optionalContentConfigPromise ||=
15031504
this._transport.getOptionalContentConfig(renderingIntent);
15041505

1505-
const intentState = this._intentStates.getOrInsertComputed(cacheKey, () =>
1506-
Object.create(null)
1506+
const intentState = this._intentStates.getOrInsertComputed(
1507+
cacheKey,
1508+
makeObj
15071509
);
15081510
// Ensure that a pending `streamReader` cancel timeout is always aborted.
15091511
if (intentState.streamReaderCancelTimeout) {
@@ -1675,7 +1677,7 @@ class PDFPageProxy {
16751677
);
16761678
const intentState = this._intentStates.getOrInsertComputed(
16771679
intentArgs.cacheKey,
1678-
() => Object.create(null)
1680+
makeObj
16791681
);
16801682
let opListTask;
16811683

src/display/canvas.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
FONT_IDENTITY_MATRIX,
2323
ImageKind,
2424
info,
25+
makeMap,
2526
OPS,
2627
shadow,
2728
TextRenderingMode,
@@ -989,10 +990,7 @@ class CanvasGraphics {
989990
: [currentTransform.slice(0, 4), fillColor]
990991
);
991992

992-
cache = this._cachedBitmapsMap.getOrInsertComputed(
993-
mainKey,
994-
() => new Map()
995-
);
993+
cache = this._cachedBitmapsMap.getOrInsertComputed(mainKey, makeMap);
996994
const cachedImage = cache.get(cacheKey);
997995
if (cachedImage && !isPatternFill) {
998996
const offsetX = Math.round(

src/display/pdf_objects.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@
1515

1616
const INITIAL_DATA = Symbol("INITIAL_DATA");
1717

18+
const dataObj = () => ({
19+
...Promise.withResolvers(),
20+
data: INITIAL_DATA,
21+
});
22+
1823
/**
1924
* A PDF document and page is built of many objects. E.g. there are objects for
2025
* fonts, images, rendering code, etc. These objects may get processed inside of
@@ -30,10 +35,7 @@ class PDFObjects {
3035
* @returns {Object}
3136
*/
3237
#ensureObj(objId) {
33-
return this.#objs.getOrInsertComputed(objId, () => ({
34-
...Promise.withResolvers(),
35-
data: INITIAL_DATA,
36-
}));
38+
return this.#objs.getOrInsertComputed(objId, dataObj);
3739
}
3840

3941
/**

src/pdf.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ import {
3333
getUuid,
3434
ImageKind,
3535
InvalidPDFException,
36+
makeMap,
37+
makeObj,
3638
MathClamp,
3739
normalizeUnicode,
3840
OPS,
@@ -123,6 +125,8 @@ globalThis.pdfjsLib = {
123125
isDataScheme,
124126
isPdfFile,
125127
isValidExplicitDest,
128+
makeMap,
129+
makeObj,
126130
MathClamp,
127131
noContextMenu,
128132
normalizeUnicode,
@@ -182,6 +186,8 @@ export {
182186
isDataScheme,
183187
isPdfFile,
184188
isValidExplicitDest,
189+
makeMap,
190+
makeObj,
185191
MathClamp,
186192
noContextMenu,
187193
normalizeUnicode,

src/shared/util.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,6 +1234,11 @@ function _isValidExplicitDest(validRef, validName, dest) {
12341234
return true;
12351235
}
12361236

1237+
// Helpers for simple `Map.prototype.getOrInsertComputed()` invocations,
1238+
// to avoid duplicate function creation.
1239+
const makeMap = () => new Map();
1240+
const makeObj = () => Object.create(null);
1241+
12371242
// TODO: Replace all occurrences of this function with `Math.clamp` once
12381243
// https://github.com/tc39/proposal-math-clamp/ is generally available.
12391244
function MathClamp(v, min, max) {
@@ -1331,6 +1336,8 @@ export {
13311336
isNodeJS,
13321337
LINE_DESCENT_FACTOR,
13331338
LINE_FACTOR,
1339+
makeMap,
1340+
makeObj,
13341341
MathClamp,
13351342
MeshFigureType,
13361343
normalizeUnicode,

test/unit/pdf_spec.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import {
2424
getUuid,
2525
ImageKind,
2626
InvalidPDFException,
27+
makeMap,
28+
makeObj,
2729
MathClamp,
2830
normalizeUnicode,
2931
OPS,
@@ -107,6 +109,8 @@ const expectedAPI = Object.freeze({
107109
isDataScheme,
108110
isPdfFile,
109111
isValidExplicitDest,
112+
makeMap,
113+
makeObj,
110114
MathClamp,
111115
noContextMenu,
112116
normalizeUnicode,

web/pdfjs.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ const {
4444
isDataScheme,
4545
isPdfFile,
4646
isValidExplicitDest,
47+
makeMap,
48+
makeObj,
4749
MathClamp,
4850
noContextMenu,
4951
normalizeUnicode,
@@ -103,6 +105,8 @@ export {
103105
isDataScheme,
104106
isPdfFile,
105107
isValidExplicitDest,
108+
makeMap,
109+
makeObj,
106110
MathClamp,
107111
noContextMenu,
108112
normalizeUnicode,

0 commit comments

Comments
 (0)