Skip to content

Commit 76b8f99

Browse files
committed
Don't use std::regex to parse floats to improve performance, see #3
1 parent a549bf0 commit 76b8f99

File tree

1 file changed

+38
-15
lines changed

1 file changed

+38
-15
lines changed

libchecktestdata.cc

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -957,26 +957,52 @@ void checktoken(command cmd)
957957
string fixed_regex("-?[0-9]+(\\.[0-9]+)?");
958958
string scien_regex("-?[0-9]+(\\.[0-9]+)?[eE][+-]?[0-9]+");
959959

960-
regex regexstr(float_regex);
961-
match_results<string::const_iterator> res;
962-
string matchstr;
963-
960+
int opt = 0; // 1 = scientific, 2 = fixed.
964961
if ( cmd.nargs()>=4 ) {
965-
if ( cmd.args[3].name()=="SCIENTIFIC" ) regexstr = scien_regex;
966-
else if ( cmd.args[3].name()=="FIXED" ) regexstr = fixed_regex;
962+
if ( cmd.args[3].name()=="SCIENTIFIC" ) opt = 1;
963+
else if ( cmd.args[3].name()=="FIXED" ) opt = 2;
967964
else {
968965
cerr << "invalid option in " << program[prognr] << endl;
969966
exit(exit_failure);
970967
}
971968
}
972969

973-
if ( !regex_search((string::const_iterator)&data[datanr],
974-
(string::const_iterator)data.end(),
975-
res,regexstr,regex_constants::match_continuous) ) {
976-
error();
970+
size_t start = datanr;
971+
// Match optional minus sign:
972+
if ( datanr<data.size() && data[datanr]=='-' ) { datanr++; charnr++; }
973+
// Match base with optional decimal dot:
974+
if ( datanr>=data.size() || !isdigit(data[datanr]) ) error("digit expected");
975+
bool dot_seen = false, first_digit = true;
976+
while ( datanr<data.size() &&
977+
(isdigit(data[datanr]) ||
978+
(!dot_seen && !first_digit && data[datanr]=='.')) ) {
979+
first_digit = false;
980+
if ( data[datanr]=='.' ) dot_seen = true;
981+
datanr++;
982+
charnr++;
977983
}
978-
size_t matchend = size_t(res[0].second-data.begin());
979-
matchstr = string(data.begin()+datanr,data.begin()+matchend);
984+
// Check that any dot is followed by digit:
985+
if ( !isdigit(data[datanr-1]) ) error("digit expected");
986+
987+
// Match exponent:
988+
if ( opt==1 || (opt==0 && datanr<data.size() && toupper(data[datanr])=='E') ) {
989+
if ( datanr>=data.size() || toupper(data[datanr])!='E' ) {
990+
error("exponent 'E' expected");
991+
}
992+
datanr++;
993+
charnr++;
994+
if ( datanr<data.size() && (data[datanr]=='-' || data[datanr]=='+') ) {
995+
datanr++;
996+
charnr++;
997+
}
998+
while ( datanr<data.size() && isdigit(data[datanr]) ) {
999+
datanr++;
1000+
charnr++;
1001+
}
1002+
if ( !isdigit(data[datanr-1]) ) error("digit expected");
1003+
}
1004+
1005+
string matchstr = data.substr(start,datanr-start+1);
9801006

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

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

9861012
if ( x<lo || x>hi ) error("value out of range");
9871013
if ( cmd.nargs()>=3 ) setvar(cmd.args[2],value_t(x));
988-
989-
charnr += matchend - datanr;
990-
datanr = matchend;
9911014
}
9921015

9931016
else if ( cmd.name()=="STRING" ) {

0 commit comments

Comments
 (0)