Middle
Kādi ir veidi, kā optimizēt darbu ar virknes C++?
sobes.tech AI
Atbilde no AI
- Izmantojiet
std::string_viewteksta nodošanai bez datu kopēšanas. - Pielietojiet
<string>un<algorithm>bibliotēku algoritmus (find,search) vietā manuālas iterācijas. - Iepriekš rezervējiet atmiņu ar
reserve, lai samazinātu pārrakstīšanas skaitu, paplašinot virkni. - Izmantojiet maza izmēra virknes optimizāciju (Small String Optimization - SSO)
std::string(ja to realizē kompilators). - Ja nepieciešama ātra virkņu apvienošana, izmantojiet
std::stringstreamvai pakāpeniski pievienojiet elementus vienai rezultāta virknei, iepriekš rezervējot vietu. - Izmantojiet īpašas bibliotēkas, kas ir optimizētas darbam ar virkņiem konkrētiem uzdevumiem (piemēram, regulārie izteiksmes).
- Novietojiet virknes statiskajā atmiņā vai pulkā, lai izvairītos no dinamiskas atmiņas piešķiršanas pastāvīgām virkņiem.
- Izmantojiet zema līmeņa C funkcijas (
memcpy,memmove) lielu datu apjomu kopēšanai, ja tas ir droši un pamatoti.
Piemērs ar std::string_view:
#include <string>
#include <string_view>
#include <iostream>
void print_string(std::string_view sv) {
std::cout << sv << std::endl;
}
int main() {
std::string s = "Hello, world!";
print_string(s); // Bez kopēšanas
const char* c_str = "Vēl viens teksts";
print_string(c_str); // Arī bez kopēšanas
return 0;
}
Piemērs ar reserve:
#include <string>
#include <iostream>
int main() {
std::string s;
s.reserve(100); // Iepriekšēja vietas rezervācija
for (int i = 0; i < 100; ++i) {
s += 'a'; // Pievieno simbolus, mazāk pārrakstīšanu
}
std::cout << "Izmērs: " << s.size() << ", Kapacitāte: " << s.capacity() << std::endl;
return 0;
}
Salīdzinājums ar virkņu apvienošanu:
#include <string>
#include <sstream>
#include <iostream>
#include <chrono>
int main() {
const int count = 1000;
std::string chunk = "abc";
// Apvienošana ar `+=` operatoru
auto start1 = std::chrono::high_resolution_clock::now();
std::string result1;
result1.reserve(count * chunk.size()); // Rezervēšana ar optimizāciju
for (int i = 0; i < count; ++i) {
result1 += chunk;
}
auto end1 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed1 = end1 - start1;
std::cout << "Operator += (ar rezervi): " << elapsed1.count() << " s" << std::endl;
// Izmantojot `stringstream`
auto start2 = std::chrono::high_resolution_clock::now();
std::stringstream ss;
for (int i = 0; i < count; ++i) {
ss << chunk;
}
std::string result2 = ss.str();
auto end2 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed2 = end2 - start2;
std::cout << "stringstream: " << elapsed2.count() << " s" << std::endl;
return 0;
}
(Piezīme: šo metožu veiktspēja var atšķirties atkarībā no kompilatora un standarta bibliotēkas).