]> git.lyx.org Git - lyx.git/commitdiff
Remove performance bottleneck in getAuthors()
authorJuergen Spitzmueller <spitz@lyx.org>
Fri, 5 Jul 2024 12:05:26 +0000 (14:05 +0200)
committerJuergen Spitzmueller <spitz@lyx.org>
Fri, 5 Jul 2024 12:05:26 +0000 (14:05 +0200)
The regex is expensive which is especially noticeable with very long
author lists.

This introduces a case-insensitive subst() variant which is much faster.

src/BiblioInfo.cpp
src/support/lstrings.cpp
src/support/lstrings.h

index 253fb3759cbb7d50a30d9d6c701dd62330c18530..e2ea4bde54e3560328871a4c1cf375e8e318276a 100644 (file)
@@ -279,12 +279,7 @@ vector<docstring> const getAuthors(docstring const & author)
        // Then, we temporarily make all " and " strings to ampersands in order
        // to handle them later on a per-char level. Note that arbitrary casing
        // ("And", "AND", "aNd", ...) is allowed in bibtex (#10465).
-       static regex const and_reg("(.* )([aA][nN][dD])( .*)");
-       smatch sub;
-       string res = to_utf8(iname);
-       while (regex_match(res, sub, and_reg))
-               res = sub.str(1) + "&" + sub.str(3);
-       iname = from_utf8(res);
+       iname = subst(iname, from_ascii(" and "), from_ascii(" & "), false);
        // Now we traverse through the string and replace the "&" by the proper
        // output in- and outside groups
        docstring name;
index 61ea5bf36a97df9f7948ee9dda522464ce3c23bf..600885f80c22f1d650d41a2580d4178b8541f9a9 100644 (file)
@@ -913,16 +913,27 @@ String const subst_string(String const & a,
 
 
 docstring const subst_string(docstring const & a,
-               docstring const & oldstr, docstring const & newstr)
+               docstring const & oldstr, docstring const & newstr,
+               bool const case_sens)
 {
        LASSERT(!oldstr.empty(), return a);
        docstring lstr = a;
        size_t i = 0;
        size_t const olen = oldstr.length();
-       while ((i = lstr.find(oldstr, i)) != string::npos) {
-               lstr.replace(i, olen, newstr);
-               i += newstr.length(); // We need to be sure that we don't
-               // use the same i over and over again.
+       if (case_sens)
+               while ((i = lstr.find(oldstr, i)) != string::npos) {
+                       lstr.replace(i, olen, newstr);
+                       i += newstr.length(); // We need to be sure that we don't
+                       // use the same i over and over again.
+               }
+       else {
+               docstring lcstr = lowercase(lstr);
+               while ((i = lcstr.find(oldstr, i)) != string::npos) {
+                       lstr.replace(i, olen, newstr);
+                       i += newstr.length(); // We need to be sure that we don't
+                       // use the same i over and over again.
+                       lcstr = lowercase(lstr);
+               }
        }
        return lstr;
 }
@@ -951,9 +962,10 @@ string const subst(string const & a,
 
 
 docstring const subst(docstring const & a,
-               docstring const & oldstr, docstring const & newstr)
+               docstring const & oldstr, docstring const & newstr,
+               bool case_sens)
 {
-       return subst_string(a, oldstr, newstr);
+       return subst_string(a, oldstr, newstr, case_sens);
 }
 
 
index 390d29c66a835a5a47341069c3aa46364488c7fe..b406f30994c39110dd5245a66384ffbc53de6988 100644 (file)
@@ -196,7 +196,8 @@ std::string const subst(std::string const & a,
 
 /// substitutes all instances of \a oldstr with \a newstr
 docstring const subst(docstring const & a,
-               docstring const & oldstr, docstring const & newstr);
+               docstring const & oldstr, docstring const & newstr,
+               bool case_sens = true);
 
 /// Count all occurrences of char \a chr inside \a str
 int count_char(std::string const & str, char chr);