Skip to content

Commit e58dde5

Browse files
authored
perf: improve regexp performance by using non-capturing groups (#58551)
1 parent 5fd65f3 commit e58dde5

File tree

2 files changed

+12
-12
lines changed

2 files changed

+12
-12
lines changed

src/compiler/utilities.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9542,7 +9542,7 @@ const wildcardCharCodes = [CharacterCodes.asterisk, CharacterCodes.question];
95429542

95439543
const commonPackageFolders: readonly string[] = ["node_modules", "bower_components", "jspm_packages"];
95449544

9545-
const implicitExcludePathRegexPattern = `(?!(${commonPackageFolders.join("|")})(/|$))`;
9545+
const implicitExcludePathRegexPattern = `(?!(?:${commonPackageFolders.join("|")})(?:/|$))`;
95469546

95479547
/** @internal */
95489548
export interface WildcardMatcher {
@@ -9558,12 +9558,12 @@ const filesMatcher: WildcardMatcher = {
95589558
* [^./] # matches everything up to the first . character (excluding directory separators)
95599559
* (\\.(?!min\\.js$))? # matches . characters but not if they are part of the .min.js file extension
95609560
*/
9561-
singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*",
9561+
singleAsteriskRegexFragment: "(?:[^./]|(?:\\.(?!min\\.js$))?)*",
95629562
/**
95639563
* Regex for the ** wildcard. Matches any number of subdirectories. When used for including
95649564
* files or directories, does not match subdirectories that start with a . character
95659565
*/
9566-
doubleAsteriskRegexFragment: `(/${implicitExcludePathRegexPattern}[^/.][^/]*)*?`,
9566+
doubleAsteriskRegexFragment: `(?:/${implicitExcludePathRegexPattern}[^/.][^/]*)*?`,
95679567
replaceWildcardCharacter: match => replaceWildcardCharacter(match, filesMatcher.singleAsteriskRegexFragment),
95689568
};
95699569

@@ -9573,13 +9573,13 @@ const directoriesMatcher: WildcardMatcher = {
95739573
* Regex for the ** wildcard. Matches any number of subdirectories. When used for including
95749574
* files or directories, does not match subdirectories that start with a . character
95759575
*/
9576-
doubleAsteriskRegexFragment: `(/${implicitExcludePathRegexPattern}[^/.][^/]*)*?`,
9576+
doubleAsteriskRegexFragment: `(?:/${implicitExcludePathRegexPattern}[^/.][^/]*)*?`,
95779577
replaceWildcardCharacter: match => replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment),
95789578
};
95799579

95809580
const excludeMatcher: WildcardMatcher = {
95819581
singleAsteriskRegexFragment: "[^/]*",
9582-
doubleAsteriskRegexFragment: "(/.+?)?",
9582+
doubleAsteriskRegexFragment: "(?:/.+?)?",
95839583
replaceWildcardCharacter: match => replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment),
95849584
};
95859585

@@ -9596,10 +9596,10 @@ export function getRegularExpressionForWildcard(specs: readonly string[] | undef
95969596
return undefined;
95979597
}
95989598

9599-
const pattern = patterns.map(pattern => `(${pattern})`).join("|");
9599+
const pattern = patterns.map(pattern => `(?:${pattern})`).join("|");
96009600
// If excluding, match "foo/bar/baz...", but if including, only allow "foo".
9601-
const terminator = usage === "exclude" ? "($|/)" : "$";
9602-
return `^(${pattern})${terminator}`;
9601+
const terminator = usage === "exclude" ? "(?:$|/)" : "$";
9602+
return `^(?:${pattern})${terminator}`;
96039603
}
96049604

96059605
/** @internal */
@@ -9624,7 +9624,7 @@ export function isImplicitGlob(lastPathComponent: string): boolean {
96249624
/** @internal */
96259625
export function getPatternFromSpec(spec: string, basePath: string, usage: "files" | "directories" | "exclude"): string | undefined {
96269626
const pattern = spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]);
9627-
return pattern && `^(${pattern})${usage === "exclude" ? "($|/)" : "$"}`;
9627+
return pattern && `^(?:${pattern})${usage === "exclude" ? "(?:$|/)" : "$"}`;
96289628
}
96299629

96309630
/** @internal */
@@ -9657,7 +9657,7 @@ export function getSubPatternFromSpec(
96579657
}
96589658
else {
96599659
if (usage === "directories") {
9660-
subpattern += "(";
9660+
subpattern += "(?:";
96619661
optionalCount++;
96629662
}
96639663

@@ -9671,7 +9671,7 @@ export function getSubPatternFromSpec(
96719671
// appear first in a component. Dotted directories and files can be included explicitly
96729672
// like so: **/.*/.*
96739673
if (component.charCodeAt(0) === CharacterCodes.asterisk) {
9674-
componentPattern += "([^./]" + singleAsteriskRegexFragment + ")?";
9674+
componentPattern += "(?:[^./]" + singleAsteriskRegexFragment + ")?";
96759675
component = component.substr(1);
96769676
}
96779677
else if (component.charCodeAt(0) === CharacterCodes.question) {

src/compiler/watch.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ export function getMatchedIncludeSpec(program: Program, fileName: string): strin
436436
const index = findIndex(configFile?.configFileSpecs?.validatedIncludeSpecs, includeSpec => {
437437
if (isJsonFile && !endsWith(includeSpec, Extension.Json)) return false;
438438
const pattern = getPatternFromSpec(includeSpec, basePath, "files");
439-
return !!pattern && getRegexFromPattern(`(${pattern})$`, useCaseSensitiveFileNames).test(fileName);
439+
return !!pattern && getRegexFromPattern(`(?:${pattern})$`, useCaseSensitiveFileNames).test(fileName);
440440
});
441441
return index !== -1 ? configFile.configFileSpecs.validatedIncludeSpecsBeforeSubstitution![index] : undefined;
442442
}

0 commit comments

Comments
 (0)