mardi 6 août 2019

How do I compare a section of a string without copying?

I have a long string that I'm iterating through, and at each iteration I compare a section of the string to a constant and store some parts of the string. In my actual code, this code runs millions of times and is the main bottleneck. I think it's due to the excessive use of std::string::substr.

#include <iostream>
#include <map>
#include <string>
#include <vector>

int main() {
    std::string str("0=My,1=comma,2=separated,3=string,0=with,3=repeated,7=IDs");
    std::vector<std::string> out0;
    std::map<std::string, std::string> out;

    size_t pos = str.find(',');

    // loop over the string, collecting "key=value" pairs
    while (pos < str.size() - 1) {
        if (str.substr(pos + 1, 2) == "0=") {
            auto newPos = str.find(',', pos + 3);
            out0.push_back(str.substr(pos + 3, newPos - pos - 3);
            pos = newPos;
        } else {
            size_t eqPos = str.find('=', pos + 1);
            auto newPos = str.find(',', eqPos + 1);
            out[str.substr(pos + 1, eqPos - pos - 1)] = str.substr(eqPos + 1, newPos - eqPos - 1);
        }
    }

    // print out the data structures (this doesn't happen in my actual code)
    std::cout << "out0:";
    for (auto& entry : out0) {
        std::cout << ' ' << entry;
    }
    std::cout << std::endl;

    std::cout << "out:";
    for (auto it : out) {
        std::cout << ' ' << it->first << '=' << it->second;
    }
}

Here are my questions:

  • How can I perform comparisons on the string without performing a copy and without writing the comparison for each character, e.g. str[pos + 1] == '0' && str[pos + 2] == '=' && ...?
  • How can I store references to substrings, instead of making copies every time I add to out0 and out?

This may be a great case for the use of char *, but I've never used it before.

Edit:

Unfortunately, I've only got C++11; otherwise, std::string_view is the best answer. Is there a way to accomplish this without std::string_view?

Aucun commentaire:

Enregistrer un commentaire