Questo è chiamato allocazione registro e il compilatore / ottimizzatore si prenderà cura di esso per te. Assicurati di attivare l'ottimizzazione. Se vuoi vedere cosa fa, basta compilare per assemblatore ... e poi imparare a leggere e capire l'assemblatore. La qualità dell'implementazione varierà, ma in generale non è necessario pensarci a meno che non si abbia un problema di prestazioni specifico.
L'unica volta che potrebbe valere la pena di riflettere su questo problema, è quando si sa che un array non può essere aliasato, ma sarà difficile per il compilatore dimostrarlo. Ad esempio,
double radius[3];
double *possible_alias = get_ptr();
...
for (int i=0; i<3; ++i) {
*possible_alias *= radius[i];
do_something_else(radius[i]);
}
se sai che l'assegnazione del puntatore non cambierà raggio [i], ma il compilatore potrebbe non essere in grado di fare affidamento su di esso, potresti scrivere
double r = radius[i];
*possible_alias *= r;
do_something_else(r);
In generale, non preoccuparti di questo tipo di micro ottimizzazione a meno che non trovi uno specifico problema di prestazioni. Risolvi i tuoi sforzi per scrivere codice chiaro, facile da eseguire il debug e capire e scegliere le giuste strutture dati e algoritmi.
Per quanto riguarda come per profilare il tuo codice, questo è un argomento enorme e il supporto dipende dalla tua piattaforma e toolchain. Sono disponibili profilatori di campionamento compilati (come gprof, per la toolchain GCC), profiler post-hoc (come VTune di Intel e il valgrind gratuito), oppure è possibile solo il tempo di eseguire esecuzioni o scrivere manualmente i propri punti di temporizzazione. È improbabile che ne valga la pena, a meno che il tuo programma non sia oggettivamente troppo lento in primo luogo.
Nota per OP: la discussione nei commenti qui sotto riguarda le situazioni in cui la CPU può essere in grado di ottimizzare questo in fase di esecuzione, anche se il compilatore non può. Almeno su piattaforme x86 moderne, riduce ulteriormente il valore del pensiero su questo.