Improve devd startup time, by tweaking some string handling routines that are

heavily used when parsing config files.  Mostly these changes avoid making
temporary copies of the strings, and avoid doing byte at a time append
operations, on the most-used code path.

On a 1.2 GHz ARM processor this reduces the time to parse the config files
from 13 to 6 seconds.

Reviewed by:	imp
Approved by:	cognet (mentor)
This commit is contained in:
ian 2013-01-30 23:37:35 +00:00
parent 1ce2adadbb
commit 85fcf6286d
2 changed files with 32 additions and 25 deletions

View File

@ -137,7 +137,7 @@ config cfg;
event_proc::event_proc() : _prio(-1)
{
// nothing
_epsvec.reserve(4);
}
event_proc::~event_proc()
@ -241,25 +241,18 @@ my_system(const char *command)
bool
action::do_action(config &c)
{
string s = c.expand_string(_cmd);
string s = c.expand_string(_cmd.c_str());
if (Dflag)
fprintf(stderr, "Executing '%s'\n", s.c_str());
my_system(s.c_str());
return (true);
}
match::match(config &c, const char *var, const char *re)
: _var(var), _re("^")
match::match(config &c, const char *var, const char *re) :
_inv(re[0] == '!'),
_var(var),
_re(c.expand_string(_inv ? re + 1 : re, "^", "$"))
{
if (!c.expand_string(string(re)).empty() &&
c.expand_string(string(re)).at(0) == '!') {
_re.append(c.expand_string(string(re)).substr(1));
_inv = 1;
} else {
_re.append(c.expand_string(string(re)));
_inv = 0;
}
_re.append("$");
regcomp(&_regex, _re.c_str(), REG_EXTENDED | REG_NOSUB | REG_ICASE);
}
@ -624,24 +617,37 @@ config::expand_one(const char *&src, string &dst)
do {
buffer.append(src++, 1);
} while (is_id_char(*src));
buffer.append("", 1);
dst.append(get_variable(buffer.c_str()));
}
const string
config::expand_string(const string &s)
config::expand_string(const char *src, const char *prepend, const char *append)
{
const char *src;
const char *var_at;
string dst;
src = s.c_str();
while (*src) {
if (*src == '$')
expand_one(src, dst);
else
dst.append(src++, 1);
/*
* 128 bytes is enough for 2427 of 2438 expansions that happen
* while parsing config files, as tested on 2013-01-30.
*/
dst.reserve(128);
if (prepend != NULL)
dst = prepend;
for (;;) {
var_at = strchr(src, '$');
if (var_at == NULL) {
dst.append(src);
break;
}
dst.append(src, var_at - src);
src = var_at;
expand_one(src, dst);
}
dst.append("", 1);
if (append != NULL)
dst.append(append);
return (dst);
}

View File

@ -90,9 +90,9 @@ public:
virtual bool do_match(config &);
virtual bool do_action(config &) { return true; }
private:
bool _inv;
std::string _var;
std::string _re;
bool _inv;
regex_t _regex;
};
@ -162,7 +162,8 @@ public:
void pop_var_table();
void set_variable(const char *var, const char *val);
const std::string &get_variable(const std::string &var);
const std::string expand_string(const std::string &var);
const std::string expand_string(const char * var,
const char * prepend = NULL, const char * append = NULL);
char *set_vars(char *);
void find_and_execute(char);
protected: