builtins.cache: Cache regular expressions
The evaluator was spending about 1% of its time compiling a small number of regexes over and over again.
This commit is contained in:
parent
d700eecea9
commit
401b5bc541
2 changed files with 9 additions and 3 deletions
|
@ -114,6 +114,9 @@ private:
|
||||||
/* Cache used by checkSourcePath(). */
|
/* Cache used by checkSourcePath(). */
|
||||||
std::unordered_map<Path, Path> resolvedPaths;
|
std::unordered_map<Path, Path> resolvedPaths;
|
||||||
|
|
||||||
|
/* Cache used by prim_match(). */
|
||||||
|
std::unordered_map<std::string, std::regex> regexCache;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
EvalState(const Strings & _searchPath, ref<Store> store);
|
EvalState(const Strings & _searchPath, ref<Store> store);
|
||||||
|
@ -314,6 +317,7 @@ private:
|
||||||
friend struct ExprOpConcatLists;
|
friend struct ExprOpConcatLists;
|
||||||
friend struct ExprSelect;
|
friend struct ExprSelect;
|
||||||
friend void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v);
|
friend void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v);
|
||||||
|
friend void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1811,19 +1811,21 @@ static void prim_hashString(EvalState & state, const Pos & pos, Value * * args,
|
||||||
|
|
||||||
/* Match a regular expression against a string and return either
|
/* Match a regular expression against a string and return either
|
||||||
‘null’ or a list containing substring matches. */
|
‘null’ or a list containing substring matches. */
|
||||||
static void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
auto re = state.forceStringNoCtx(*args[0], pos);
|
auto re = state.forceStringNoCtx(*args[0], pos);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
std::regex regex(re, std::regex::extended);
|
auto regex = state.regexCache.find(re);
|
||||||
|
if (regex == state.regexCache.end())
|
||||||
|
regex = state.regexCache.emplace(re, std::regex(re, std::regex::extended)).first;
|
||||||
|
|
||||||
PathSet context;
|
PathSet context;
|
||||||
const std::string str = state.forceString(*args[1], context, pos);
|
const std::string str = state.forceString(*args[1], context, pos);
|
||||||
|
|
||||||
std::smatch match;
|
std::smatch match;
|
||||||
if (!std::regex_match(str, match, regex)) {
|
if (!std::regex_match(str, match, regex->second)) {
|
||||||
mkNull(v);
|
mkNull(v);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue