Skip to content

Commit ac2e11d

Browse files
committed
Switch read_matlab() hotspot regex->istringstream
This gets us another factor of 2.5 speed improvement, so we're now about 15x faster than the original read_matlab() in total. That's not perfect but it's fast enough that I don't think I'll bother to try manual char-fiddling.
1 parent 7bdf3d0 commit ac2e11d

1 file changed

Lines changed: 15 additions & 16 deletions

File tree

src/numerics/sparse_matrix.C

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -619,8 +619,6 @@ void SparseMatrix<T>::read_matlab(const std::string & filename)
619619
// more robust to formatting.
620620
const std::regex start_regex // assignment like "zzz = ["
621621
("\\s*\\w+\\s*=\\s*\\[");
622-
const std::regex entry_regex // row/col/val like "1 1 -2.0e-4"
623-
("(\\d+)\\s+(\\d+)\\s+([+-]?(\\d+([.]\\d*)?([eE][+-]?\\d+)?|[.]\\d+([eE][+-]?\\d+)?))");
624622
const std::regex end_regex // end of assignment
625623
("^[^%]*\\]");
626624

@@ -650,6 +648,7 @@ void SparseMatrix<T>::read_matlab(const std::string & filename)
650648
// way to get the size is if it ended up in a comment
651649
const std::regex size_regex // comment like "% size = 8 8"
652650
("%\\s*[Ss][Ii][Zz][Ee]\\s*=\\s*(\\d+)\\s+(\\d+)");
651+
const std::string whitespace = " \t";
653652

654653
bool have_started = false;
655654
bool have_ended = false;
@@ -663,23 +662,23 @@ void SparseMatrix<T>::read_matlab(const std::string & filename)
663662
{
664663
std::smatch sm;
665664

666-
if (std::regex_search(line, sm, entry_regex))
667-
{
668-
libmesh_error_msg_if
669-
(!have_started, "Confused by premature entries in matrix file " << filename);
665+
// First, try to match an entry. This is the most common
666+
// case so we won't rely on slow std::regex for it.
667+
// stringstream is at least an improvement over that.
668+
669+
// Look for row/col/val like "1 1 -2.0e-4"
670670

671-
const std::string istr = sm[1];
672-
const std::string jstr = sm[2];
673-
const std::string cstr = sm[3];
671+
std::istringstream l(line);
674672

675-
std::size_t i = std::stoull(istr);
676-
std::size_t j = std::stoull(jstr);
673+
std::size_t i, j;
674+
T value;
677675

678-
// Try to be compatible with
679-
// higher-than-double-precision T
680-
std::stringstream ss(cstr);
681-
T value;
682-
ss >> value;
676+
l >> i >> j >> value;
677+
678+
if (!l.fail())
679+
{
680+
libmesh_error_msg_if
681+
(!have_started, "Confused by premature entries in matrix file " << filename);
683682

684683
entries.emplace_back(cast_int<numeric_index_type>(i),
685684
cast_int<numeric_index_type>(j),

0 commit comments

Comments
 (0)