mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 02:06:01 +02:00
Bug 565553 - Improve performance of build command parsers with large number of files
When possible, precompute the group number in the replacement expression when parsing option strings, instead of calling replaceAll which is slower. If the replacement expression is not a simple numbered group, fall-back to replaceAll. I have benchmarked this save between 200ms to 2sec depending on the project size. Change-Id: Id48fdcf476e2d1739522c9267e214f4c88bf316a Signed-off-by: Marc-Andre Laperle <malaperle@gmail.com>
This commit is contained in:
parent
3abe3d28e6
commit
f5531cee19
1 changed files with 37 additions and 15 deletions
|
@ -147,14 +147,16 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
|
||||||
protected static abstract class AbstractOptionParser {
|
protected static abstract class AbstractOptionParser {
|
||||||
private final int kind;
|
private final int kind;
|
||||||
private final Pattern pattern;
|
private final Pattern pattern;
|
||||||
private final String nameExpression;
|
|
||||||
private final String valueExpression;
|
|
||||||
private final int extraFlag;
|
private final int extraFlag;
|
||||||
|
|
||||||
private String parsedName;
|
private String parsedName;
|
||||||
private String parsedValue;
|
private String parsedValue;
|
||||||
private final Pattern removeExtraFileNamePattern;
|
private final Pattern removeExtraFileNamePattern;
|
||||||
|
|
||||||
|
private static final Pattern numGroupPattern = Pattern.compile("\\$(\\d+)"); //$NON-NLS-1$
|
||||||
|
private final MatcherReplacement nameMatcherReplacement;
|
||||||
|
private final MatcherReplacement valueMatcherReplacement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
|
@ -169,12 +171,41 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
|
||||||
public AbstractOptionParser(int kind, String pattern, String nameExpression, String valueExpression,
|
public AbstractOptionParser(int kind, String pattern, String nameExpression, String valueExpression,
|
||||||
int extraFlag) {
|
int extraFlag) {
|
||||||
this.kind = kind;
|
this.kind = kind;
|
||||||
this.nameExpression = nameExpression;
|
|
||||||
this.valueExpression = valueExpression;
|
|
||||||
this.extraFlag = extraFlag;
|
this.extraFlag = extraFlag;
|
||||||
|
|
||||||
this.pattern = Pattern.compile(pattern);
|
this.pattern = Pattern.compile(pattern);
|
||||||
this.removeExtraFileNamePattern = Pattern.compile("(" + pattern + ").*"); //$NON-NLS-1$ //$NON-NLS-2$
|
this.removeExtraFileNamePattern = Pattern.compile("(" + pattern + ").*"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
|
||||||
|
nameMatcherReplacement = new MatcherReplacement(nameExpression);
|
||||||
|
valueMatcherReplacement = new MatcherReplacement(valueExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Represents a replacement to be applied on a matcher, pre-calculating the group number used in the replacement if possible.
|
||||||
|
private static class MatcherReplacement {
|
||||||
|
private final String replacementExpression;
|
||||||
|
private final int replacementGroupNum;
|
||||||
|
|
||||||
|
private MatcherReplacement(String replacementExpression) {
|
||||||
|
this.replacementExpression = replacementExpression;
|
||||||
|
int groupNum = -1;
|
||||||
|
if (replacementExpression != null) {
|
||||||
|
// If the expression is just a single numbered group reference (the common case), we can predetermine
|
||||||
|
// which group we will need to retrieve on the matcher when we will parse the option string.
|
||||||
|
Matcher numGroupMatcher = numGroupPattern.matcher(replacementExpression);
|
||||||
|
if (numGroupMatcher.matches())
|
||||||
|
groupNum = Integer.parseInt(numGroupMatcher.group(1));
|
||||||
|
}
|
||||||
|
replacementGroupNum = groupNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String replace(Matcher matcher) {
|
||||||
|
if (replacementGroupNum != -1)
|
||||||
|
return matcher.group(replacementGroupNum);
|
||||||
|
// The expression is not a simple numbered group, fall-back to normal replacement (slow).
|
||||||
|
if (replacementExpression != null)
|
||||||
|
return matcher.replaceAll(replacementExpression);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -207,15 +238,6 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
|
||||||
return kind == ICSettingEntry.INCLUDE_PATH || kind == ICSettingEntry.LIBRARY_PATH;
|
return kind == ICSettingEntry.INCLUDE_PATH || kind == ICSettingEntry.LIBRARY_PATH;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return value represented by the capturing group expression.
|
|
||||||
*/
|
|
||||||
private String parseStr(Matcher matcher, String str) {
|
|
||||||
if (str != null)
|
|
||||||
return matcher.replaceAll(str);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for a match and parse a portion of input string representing a single option
|
* Test for a match and parse a portion of input string representing a single option
|
||||||
* to retrieve name and value.
|
* to retrieve name and value.
|
||||||
|
@ -236,8 +258,8 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
|
||||||
Matcher matcher = pattern.matcher(option);
|
Matcher matcher = pattern.matcher(option);
|
||||||
boolean isMatch = matcher.matches();
|
boolean isMatch = matcher.matches();
|
||||||
if (isMatch) {
|
if (isMatch) {
|
||||||
parsedName = parseStr(matcher, nameExpression);
|
parsedName = nameMatcherReplacement.replace(matcher);
|
||||||
parsedValue = parseStr(matcher, valueExpression);
|
parsedValue = valueMatcherReplacement.replace(matcher);
|
||||||
}
|
}
|
||||||
return isMatch;
|
return isMatch;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue