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:
str[pos + 1] == '0' && str[pos + 2] == '=' && ...
?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 the storage of references without std::string_view
?
If you have C++17, you can use string_view
thus: (untested code):
string_view sv{str.data() + pos, 2};
if (sv == "0=") ...
No copies. Or even (all in one go):
if (string_view{str.data() + pos, 2} == "0=") ...
If you don't have string_view
, you can use char_traits
:
if (std::char_traits<char>::compare(str.data() + pos, "0=", 2) == 0) ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With