0Pricing
C++ Academy · Lezione

Misurare le prestazioni del codice

Eseguire benchmark con chrono

Misurare le prestazioni del codice è una lezione C++ Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C++ Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C++ Academy include 4 lezioni in totale.

Perché fare benchmark

Misurare il tempo di esecuzione del codice aiuta a individuare i colli di bottiglia e a verificare le ottimizzazioni. Con <chrono> si ottiene una misurazione del tempo portabile e sicura dal punto di vista dei tipi.

  • Misuri prima di ottimizzare.
  • Utilizzi un orologio stabile per ottenere intervalli affidabili.
#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;
    auto start = steady_clock::now();
    auto end = steady_clock::now();
    std::cout << "Timed a block: " << ((end - start).count() >= 0) << '\n';
    return 0;
}

Lo schema di base

Lo schema per i benchmark è sempre lo stesso: catturi now() prima del lavoro, lo esegua, catturi now() dopo e calcoli la differenza.

#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;
    auto start = steady_clock::now();
    long sum = 0;
    for (int i = 0; i < 100000; ++i) sum += i;
    auto end = steady_clock::now();
    std::cout << "Sum: " << sum << ", elapsed >= 0: " << ((end - start).count() >= 0) << '\n';
    return 0;
}

Scelta dell'unità

Scelga l'unità adatta al carico di lavoro. Utilizzi microseconds o nanoseconds per i cicli rapidi e milliseconds per le attività più impegnative.

#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;
    auto start = steady_clock::now();
    long sum = 0;
    for (int i = 0; i < 500000; ++i) sum += i;
    auto end = steady_clock::now();
    auto us = duration_cast<microseconds>(end - start);
    std::cout << "Result: " << sum << ", us non-negative: " << (us.count() >= 0) << '\n';
    return 0;
}

Misurazione del tempo in virgola mobile

Per ottenere secondi leggibili con valori frazionari, utilizzi una duration<double> così da conservare la precisione inferiore al secondo.

#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;
    auto start = steady_clock::now();
    long sum = 0;
    for (int i = 0; i < 200000; ++i) sum += i % 7;
    auto end = steady_clock::now();
    duration<double> secs = end - start;
    std::cout << "Computed " << sum << ", seconds >= 0: " << (secs.count() >= 0) << '\n';
    return 0;
}

Un timer riutilizzabile

Racchiuda lo schema in un piccolo helper, così potrà misurare in modo ordinato il tempo di qualsiasi oggetto chiamabile senza ripetere il codice.

#include <iostream>
#include <chrono>

long long timeWork() {
    using namespace std::chrono;
    auto s = steady_clock::now();
    long acc = 0;
    for (int i = 0; i < 100000; ++i) acc += i;
    auto e = steady_clock::now();
    return duration_cast<microseconds>(e - s).count();
}

int main() {
    std::cout << "Microseconds non-negative: " << (timeWork() >= 0) << '\n';
    return 0;
}

Evitare l'eliminazione del codice inutilizzato

I compilatori possono eliminare il lavoro il cui risultato non viene utilizzato, invalidando i benchmark. Utilizzi sempre il risultato, ad esempio stampandolo o accumulandolo in una variabile osservabile.

#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;
    auto s = steady_clock::now();
    volatile long sink = 0;
    for (int i = 0; i < 100000; ++i) sink += i;
    auto e = steady_clock::now();
    std::cout << "Sink used: " << (sink > 0) << ", elapsed >= 0: " << ((e - s).count() >= 0) << '\n';
    return 0;
}

Esecuzioni di riscaldamento

La prima esecuzione può essere più lenta a causa delle cache e dell'inizializzazione differita. Esegua un passaggio di warm-up prima della misurazione per ottenere valori più stabili.

#include <iostream>
#include <chrono>

long work() {
    long a = 0;
    for (int i = 0; i < 50000; ++i) a += i;
    return a;
}

int main() {
    using namespace std::chrono;
    work();
    auto s = steady_clock::now();
    long r = work();
    auto e = steady_clock::now();
    std::cout << r << " measured, ok: " << ((e - s).count() >= 0) << '\n';
    return 0;
}

Media di più esecuzioni

Una singola misurazione è soggetta a rumore. Esegua il lavoro molte volte, sommi le durate trascorse e divida il totale per ottenere una media stabile.

#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;
    long long total = 0;
    const int runs = 5;
    for (int r = 0; r < runs; ++r) {
        auto s = steady_clock::now();
        long acc = 0;
        for (int i = 0; i < 100000; ++i) acc += i;
        auto e = steady_clock::now();
        total += duration_cast<microseconds>(e - s).count();
    }
    std::cout << "Average us non-negative: " << ((total / runs) >= 0) << '\n';
    return 0;
}

Confrontare due approcci

Il benchmarking è particolarmente utile per confrontare le implementazioni. Misuri ciascuna nello stesso modo e confronti le durate ottenute.

#include <iostream>
#include <chrono>
#include <vector>

int main() {
    using namespace std::chrono;
    std::vector<int> v;
    auto s1 = steady_clock::now();
    for (int i = 0; i < 10000; ++i) v.push_back(i);
    auto e1 = steady_clock::now();
    v.clear();
    v.reserve(10000);
    auto s2 = steady_clock::now();
    for (int i = 0; i < 10000; ++i) v.push_back(i);
    auto e2 = steady_clock::now();
    std::cout << "Both timed: " << (((e1 - s1).count() >= 0) && ((e2 - s2).count() >= 0)) << '\n';
    return 0;
}

Attenzione alla risoluzione

Se il lavoro misurato dura meno di un intervallo dell'orologio, potreste leggere zero. Eseguite il lavoro un numero sufficiente di volte per superare la risoluzione dell'orologio.

#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;
    auto s = steady_clock::now();
    int x = 1 + 1;
    auto e = steady_clock::now();
    auto ns = duration_cast<nanoseconds>(e - s).count();
    std::cout << "x=" << x << ", tiny work may read low: " << (ns >= 0) << '\n';
    return 0;
}

Comunicare i risultati

Convertite la durata finale in un'unità leggibile e stampatela. Mantenete visibile il risultato utilizzato, così l'ottimizzatore non potrà eliminare il lavoro.

#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;
    auto s = steady_clock::now();
    long acc = 0;
    for (int i = 0; i < 300000; ++i) acc += (i * 3) % 11;
    auto e = steady_clock::now();
    auto ms = duration_cast<milliseconds>(e - s).count();
    std::cout << "acc=" << acc << ", ms >= 0: " << (ms >= 0) << '\n';
    return 0;
}

Verifica rapida

Verificate la vostra comprensione delle insidie del benchmarking.

Riepilogo

Avete imparato a eseguire il benchmarking del codice con <chrono>:

  • acquisire steady_clock::now() prima e dopo, quindi sottrarre i valori
  • scegliere un'unità appropriata con duration_cast
  • eseguire il riscaldamento, calcolare la media di più esecuzioni e utilizzare i risultati per impedire l'eliminazione del codice inutile
  • prestare attenzione alla risoluzione dell'orologio per carichi di lavoro molto piccoli

Ora esplorerete i tipi C++20 per calendari e fusi orari.

Domande Frequenti

La lezione «Misurare le prestazioni del codice» è gratuita?

Sì — il testo completo di «Misurare le prestazioni del codice» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C++ Academy, passa a CoddyKit PRO. Il corso C++ Academy include 4 lezioni in totale.

Cosa imparerò in «Misurare le prestazioni del codice»?

Eseguire benchmark con chrono Eserciti C++ Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C++ Academy?

Non è richiesta alcuna esperienza precedente. C++ Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «Misurare le prestazioni del codice»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C++ Academy?

Sì. Ogni lezione C++ Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Durate e orologi
  2. Punti nel tempo
  3. Misurare le prestazioni del codice
  4. Calendario e fusi orari
← Torna a C++ Academy