Skip to content

Commit

Permalink
Don't use std::regex to parse floats to improve performance, see #3
Browse files Browse the repository at this point in the history
  • Loading branch information
eldering committed Aug 13, 2016
1 parent a549bf0 commit 76b8f99
Showing 1 changed file with 38 additions and 15 deletions.
53 changes: 38 additions & 15 deletions libchecktestdata.cc
Original file line number Diff line number Diff line change
Expand Up @@ -957,26 +957,52 @@ void checktoken(command cmd)
string fixed_regex("-?[0-9]+(\\.[0-9]+)?");
string scien_regex("-?[0-9]+(\\.[0-9]+)?[eE][+-]?[0-9]+");

regex regexstr(float_regex);
match_results<string::const_iterator> res;
string matchstr;

int opt = 0; // 1 = scientific, 2 = fixed.
if ( cmd.nargs()>=4 ) {
if ( cmd.args[3].name()=="SCIENTIFIC" ) regexstr = scien_regex;
else if ( cmd.args[3].name()=="FIXED" ) regexstr = fixed_regex;
if ( cmd.args[3].name()=="SCIENTIFIC" ) opt = 1;
else if ( cmd.args[3].name()=="FIXED" ) opt = 2;
else {
cerr << "invalid option in " << program[prognr] << endl;
exit(exit_failure);
}
}

if ( !regex_search((string::const_iterator)&data[datanr],
(string::const_iterator)data.end(),
res,regexstr,regex_constants::match_continuous) ) {
error();
size_t start = datanr;
// Match optional minus sign:
if ( datanr<data.size() && data[datanr]=='-' ) { datanr++; charnr++; }
// Match base with optional decimal dot:
if ( datanr>=data.size() || !isdigit(data[datanr]) ) error("digit expected");
bool dot_seen = false, first_digit = true;
while ( datanr<data.size() &&
(isdigit(data[datanr]) ||
(!dot_seen && !first_digit && data[datanr]=='.')) ) {
first_digit = false;
if ( data[datanr]=='.' ) dot_seen = true;
datanr++;
charnr++;
}
size_t matchend = size_t(res[0].second-data.begin());
matchstr = string(data.begin()+datanr,data.begin()+matchend);
// Check that any dot is followed by digit:
if ( !isdigit(data[datanr-1]) ) error("digit expected");

// Match exponent:
if ( opt==1 || (opt==0 && datanr<data.size() && toupper(data[datanr])=='E') ) {
if ( datanr>=data.size() || toupper(data[datanr])!='E' ) {
error("exponent 'E' expected");
}
datanr++;
charnr++;
if ( datanr<data.size() && (data[datanr]=='-' || data[datanr]=='+') ) {
datanr++;
charnr++;
}
while ( datanr<data.size() && isdigit(data[datanr]) ) {
datanr++;
charnr++;
}
if ( !isdigit(data[datanr-1]) ) error("digit expected");
}

string matchstr = data.substr(start,datanr-start+1);

mpf_class x(matchstr,4*matchstr.length());

Expand All @@ -985,9 +1011,6 @@ void checktoken(command cmd)

if ( x<lo || x>hi ) error("value out of range");
if ( cmd.nargs()>=3 ) setvar(cmd.args[2],value_t(x));

charnr += matchend - datanr;
datanr = matchend;
}

else if ( cmd.name()=="STRING" ) {
Expand Down

0 comments on commit 76b8f99

Please sign in to comment.