Notatnik techniczny

Sprintf a wydajność

Podczas doświadczeń z własną implementacją funkcji kryptograficznej MD5 natrafiłem na problem wydajnościowy z sprintf. Zobaczcie sami…

Wydajność funkcji sprintf

Mamy dwa przykładowe listingi, oba obliczają 5 milionów razy skrót kryptograficzny pewnego łańcucha tekstowego. Pierwszy z nich oblicza skrót ciągle tego samego łańcucha tekstowego, drugi formatuje tekst przy wykorzystaniu funkcji sprintf. Jak myślicie, jak bardzo wariant drugi będzie wolniejszy?

int main() {
    md5_computer md5Computer;
    constexpr uint32_t ILOSC = 5000000;
    string t1 = "JAKIS TEKST.......................";
 
    chrono::steady_clock::time_point begin = chrono::steady_clock::now();
    int text_len = t1.size();
    for (uint32_t i = 0; i < ILOSC; ++i)
    {
        const uint8_t *digest = md5Computer.hash_it(t1.c_str(), text_len);
    }
 
 
    auto delta_time = chrono::steady_clock::now() - begin;
    double delta_time_ms = chrono::duration_cast<chrono::milliseconds>(delta_time).count();
    double hash_per_sec = ILOSC / delta_time_ms * 1000.0;
    cout << "hashs per sec = " << hash_per_sec / 1000000.0;
    cout << " M  time: " << delta_time_ms << " ms" << endl; 
    return 0;
}
int main() {
    md5_computer md5Computer;
    constexpr uint32_t ILOSC = 5000000;
    string t1 = "JAKIS TEKST.......................";
 
    chrono::steady_clock::time_point begin = chrono::steady_clock::now();
    int text_len = t1.size();
    char buf[100];
    for (uint32_t i = 0; i < ILOSC; ++i)
    {
        sprintf( buf,"JAKIS TEKST.....[%d]..........", i );
        const uint8_t *digest = md5Computer.hash_it(buf, 30);
    }
 
 
    auto delta_time = chrono::steady_clock::now() - begin;
    double delta_time_ms = chrono::duration_cast<chrono::milliseconds>(delta_time).count();
    double hash_per_sec = ILOSC / delta_time_ms * 1000.0;
    cout << "hashs per sec = " << hash_per_sec / 1000000.0;
    cout << " M  time: " << delta_time_ms << " ms" << endl; 
    return 0;
}

Osobiście byłem zaskoczony aż takim pogorszeniem wydajności.

  Bez sprintf Z sprintf
Szybkość 8 Mhash/s 0.47 Mhash/s
Czas wykonania 0.62s 10.6s