misurare prima di ottimizzare
ottimizzare senza misurare porta a regressioni. usa benchmark piccoli e ripetibili.
#include <chrono>
auto start = std::chrono::high_resolution_clock::now();
// work
auto end = std::chrono::high_resolution_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
flag del compilatore
abilita ottimizzazioni e debug separati. usa profili diversi per dev e release.
g++ -O2 -march=native -DNDEBUG main.cpp -o app
# build debug
g++ -O0 -g main.cpp -o app_debug
cache e layout dati
il layout in memoria conta più di molte micro-ottimizzazioni. preferisci strutture contigue.
struct particle {
float x, y, z;
float vx, vy, vz;
};
std::vector<particle> particles;
evita pointer chasing quando possibile: riduce cache miss.
strumenti di profiling
usa strumenti come perf, instruments o visual studio profiler per capire i colli di bottiglia.
- identifica funzioni hot
- analizza cache miss e branch
- verifica allocazioni e frammentazione
esercizi
costruisci un benchmark con due implementazioni e confronta tempi e allocazioni.
ottimizza una funzione critica usando reserve e misurando prima/dopo.
checklist
- misura prima di ottimizzare
- usa build release per benchmark
- controlla allocazioni e cache
- documenta i risultati
panoramica
In questo capitolo su performance e profiling, misura prima, ottimizza dopo: pipeline pulita. L'obiettivo è trasformare i concetti in micro-pattern riutilizzabili con esempi piccoli e verificabili.
Lavora in sequenza: leggi, prova, modifica gli snippet e annota i trade-off principali (performance, leggibilità, manutenzione).
badge: performance advanced
obiettivi
- capire e applicare misurare in uno scenario reale
- capire e applicare flag compilatore in uno scenario reale
- capire e applicare cache e layout in uno scenario reale
- capire e applicare strumenti in uno scenario reale
scheda rapida
#include <iostream>
#include <vector>
int main() {
std::vector<int> dati{1, 2, 3};
for (auto &v : dati) {
v *= 2;
}
for (const auto &v : dati) {
std::cout << v << " ";
}
std::cout << "\n";
return 0;
}
Adatta questo scheletro agli esempi della lezione e sostituisci i dati con il tuo dominio.
tips
- compila con warning elevati
- preferisci RAII
- usa const ovunque possibile
- ottimizza data layout
- riduci cache miss
- evita virtual call calde
tip: Spesso la performance è una questione di memoria, non di CPU.
mini progetto
Refactor di una struct per migliorare cache locality.
- riordina campi della struct
- usa array of struct vs struct of array
- misura l'impatto
- documenta trade-off
output atteso: uno script o query ripetibile con risultati verificabili.