Skip to content

Commit 4b3cc3c

Browse files
zeusdeuxrichardlau
authored andcommittedMar 25, 2024
loader: speed up line length calc used by moduleProvider
When using a loader, for say TypeScript, the esm loader invokes the `lineLengths` function via `maybeCacheSourceMap` when sourcemaps are enabled. Therefore, `lineLengths` ends up getting called quite often when running large servers written in TypeScript for example. Making `lineLengths` faster should therefore speed up server startup times for anyone using a loader with node with sourcemaps enabled. The change itself is fairly simple and is all about removing creation of unnecessary memory and iterating the whole source content only once with the hope of making the function cache friendly. PR-URL: #50969 Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io> Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br> Reviewed-By: Jacob Smith <jacob@frende.me>
1 parent 1e923f1 commit 4b3cc3c

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed
 

‎lib/internal/source_map/source_map_cache.js

+20-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
'use strict';
22

33
const {
4-
ArrayPrototypeMap,
4+
ArrayPrototypePush,
55
JSONParse,
66
ObjectKeys,
77
RegExpPrototypeExec,
8-
RegExpPrototypeSymbolSplit,
98
SafeMap,
9+
StringPrototypeCodePointAt,
1010
StringPrototypeSplit,
1111
} = primordials;
1212

@@ -205,14 +205,26 @@ function dataFromUrl(sourceURL, sourceMappingURL) {
205205
// from. This allows translation from byte offset V8 coverage reports,
206206
// to line/column offset Source Map V3.
207207
function lineLengths(content) {
208-
// We purposefully keep \r as part of the line-length calculation, in
209-
// cases where there is a \r\n separator, so that this can be taken into
210-
// account in coverage calculations.
211-
return ArrayPrototypeMap(RegExpPrototypeSymbolSplit(/\n|\u2028|\u2029/, content), (line) => {
212-
return line.length;
213-
});
208+
const contentLength = content.length;
209+
const output = [];
210+
let lineLength = 0;
211+
for (let i = 0; i < contentLength; i++, lineLength++) {
212+
const codePoint = StringPrototypeCodePointAt(content, i);
213+
214+
// We purposefully keep \r as part of the line-length calculation, in
215+
// cases where there is a \r\n separator, so that this can be taken into
216+
// account in coverage calculations.
217+
// codepoints for \n (new line), \u2028 (line separator) and \u2029 (paragraph separator)
218+
if (codePoint === 10 || codePoint === 0x2028 || codePoint === 0x2029) {
219+
ArrayPrototypePush(output, lineLength);
220+
lineLength = -1; // To not count the matched codePoint such as \n character
221+
}
222+
}
223+
ArrayPrototypePush(output, lineLength);
224+
return output;
214225
}
215226

227+
216228
function sourceMapFromFile(mapURL) {
217229
try {
218230
const fs = require('fs');

0 commit comments

Comments
 (0)
Please sign in to comment.