Sobes.tech
Middle

Kādi ir veidi, kā optimizēt darbu ar virknes C++?

sobes.tech AI

Atbilde no AI

  1. Izmantojiet std::string_view teksta nodošanai bez datu kopēšanas.
  2. Pielietojiet <string> un <algorithm> bibliotēku algoritmus (find, search) vietā manuālas iterācijas.
  3. Iepriekš rezervējiet atmiņu ar reserve, lai samazinātu pārrakstīšanas skaitu, paplašinot virkni.
  4. Izmantojiet maza izmēra virknes optimizāciju (Small String Optimization - SSO) std::string (ja to realizē kompilators).
  5. Ja nepieciešama ātra virkņu apvienošana, izmantojiet std::stringstream vai pakāpeniski pievienojiet elementus vienai rezultāta virknei, iepriekš rezervējot vietu.
  6. Izmantojiet īpašas bibliotēkas, kas ir optimizētas darbam ar virkņiem konkrētiem uzdevumiem (piemēram, regulārie izteiksmes).
  7. Novietojiet virknes statiskajā atmiņā vai pulkā, lai izvairītos no dinamiskas atmiņas piešķiršanas pastāvīgām virkņiem.
  8. 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).