Middle
Kokie yra būdai optimizuoti darbą su eilutėmis C++?
sobes.tech AI
Atsakymas iš AI
- Naudokite
std::string_viewperduotiems eilutėms be duomenų kopijavimo. - Taikykite
<string>ir<algorithm>bibliotekų algoritmus (find,search) vietoje rankinio iteravimo. - Iš anksto rezervuokite atmintį naudodami
reserve, kad sumažintumėte peradresavimų skaičių didinant eilutę. - Naudokite mažo dydžio eilutės buferį (Small String Optimization - SSO)
std::string(jei tai įgyvendina kompiliatorius). - Jei reikia greitos didelio kiekio eilutės sujungimo, naudokite
std::stringstreamarba pridėkite elementus po vieną į vieną rezultatą, iš anksto rezervuodami vietą. - Naudokite specialias bibliotekas, optimizuotas darbui su eilutėmis, skirtas konkrečioms užduotims (pavyzdžiui, reguliarios išraiškos).
- Laikykite eilutes statinėje atmintyje arba pulte, kad išvengtumėte dinaminio paskirstymo dirbant su nuolatinėmis eilutėmis.
- Naudokite žemo lygio C funkcijas (
memcpy,memmove) didelių duomenų kopijavimui, jei tai saugu ir pagrįsta.
Pavyzdys naudojant 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); // Be kopijavimo
const char* c_str = "Dar vienas eilutė";
print_string(c_str); // Taip pat be kopijavimo
return 0;
}
Pavyzdys naudojant reserve:
#include <string>
#include <iostream>
int main() {
std::string s;
s.reserve(100); // Iš anksto rezervuokite vietą
for (int i = 0; i < 100; ++i) {
s += 'a'; // Pridėkite simbolius, mažiau peradresavimų
}
std::cout << "Dydis: " << s.size() << ", Talpa: " << s.capacity() << std::endl;
return 0;
}
Lyginant sujungimą:
#include <string>
#include <sstream>
#include <iostream>
#include <chrono>
int main() {
const int count = 1000;
std::string chunk = "abc";
// Sujungimas naudojant `+=` operatorių
auto start1 = std::chrono::high_resolution_clock::now();
std::string result1;
result1.reserve(count * chunk.size()); // Optimizacija su rezervavimu
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 += (su rezervu): " << elapsed1.count() << " s" << std::endl;
// Naudojant `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;
}
(Pastaba: šių metodų našumas gali skirtis priklausomai nuo kompiliatoriaus ir standartinės bibliotekos).