Questa domanda ha già una buona risposta. Ma mi piacerebbe aggiungere un altro suggerimento:
Lavoro all'interno del quadro <chrono>
. Costruisci il tuo orologio. Costruisci il tuo punto temporale. Costruisci la tua durata. Il framework <chrono>
è molto personalizzabile. Lavorando all'interno di quel sistema, non solo impari lo std::chrono
, ma quando il tuo venditore inizia a spedire gli orologi di cui sei soddisfatto, sarà banale trasferire il tuo codice dal tuo crono :: clock a mano a std::high_resolution_clock
(o qualsiasi altra cosa).
Prima, però, un minorenne critica sulla tua codice originale:
std::cout << "seconds since start: " << ((double) difference/1000000);
Ogni volta che ti vedi l'introduzione di costanti di conversione (come 1000000) per ottenere ciò che si vuole, non si sta usando chrono
correttamente. Il tuo codice non è errato, solo fragile. Sei il sicuro di hai il giusto numero di zeri in quella costante ?!
Anche in questo semplice esempio si dovrebbe dire a te stesso:
Voglio vedere l'uscita in termini di secondi rappresentati da un doppio.
E quindi si dovrebbe usare chrono
farlo per voi. E 'molto facile una volta che si impara:
typedef std::chrono::duration<double> sec;
sec difference = end - start;
std::cout << "seconds since start: " << difference.count() << '\n';
La prima riga crea un tipo con un periodo di 1 secondo, rappresentato da un doppio.
La seconda riga sottrae semplicemente i tuoi time_points e li assegna al tipo di durata personalizzato. La conversione dalle unità di steady_clock::time_point
alla durata personalizzata (un doppio secondo) viene eseguita automaticamente dalla libreria chrono
.Questo è molto più semplice:
auto difference = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
E poi finalmente basta stampare il risultato con la funzione .count()
membro. Anche questo è molto più semplice rispetto:
std::cout << "seconds since start: " << ((double) difference/1000000);
Ma dal momento che non sei felice con la precisione di std::chrono::steady_clock
, e si ha accesso a QueryPerformanceCounter, si può fare di meglio. Puoi costruire il tuo orologio su QueryPerformanceCounter.
<disclaimer>
non ho un sistema Windows per testare il codice seguente.
</disclaimer>
struct my_clock
{
typedef double rep;
typedef std::ratio<1> period;
typedef std::chrono::duration<rep, period> duration;
typedef std::chrono::time_point<my_clock> time_point;
static const bool is_steady = false;
static time_point now()
{
static const long long frequency = init_frequency();
long long t;
QueryPerformanceCounter(&t);
return time_point(duration(static_cast<rep>(t)/frequency));
}
private:
static long long init_frequency()
{
long long f;
QueryPerformanceFrequency(&f);
return f;
}
};
Dal momento che si voleva la vostra uscita in termini di un doppio secondo, ho fatto la rep
di questo orologio un double
e la period
1 secondo. Si potrebbe facilmente realizzare l'integrale rep
e l'period
qualche altra unità come microsecondi o nanosecondi. È sufficiente regolare i valori typedef
e la conversione da QueryPerformanceCounter
a duration
in now()
.
E ora il codice può guardare molto come il tuo codice originale:
int main()
{
auto start = my_clock::now();
for (unsigned long long int i = 0; i < 10000; ++i) {
std::vector<int> v(i, 1);
}
auto end = my_clock::now();
auto difference = end - start;
std::cout << "seconds since start: " << difference.count() << '\n';
}
Ma senza le costanti di conversione in codice a mano, e con (quello che spero è) la precisione sufficiente per la vostra esigenze. E con un molto più facile porting percorso per una futura implementazione std::chrono::steady_clock
.
<chrono>
è stato progettato per essere una libreria estendibile. Si prega di estenderlo. :-)
Provare invece 'std :: chrono :: high_resolution_clock'. –
@KerrekSB: Questo è un buon suggerimento, ma 'steady_clock :: now()' dovrebbe essere già preciso ai nanosecondi, o almeno ai tick (intervalli di 100 nanosecondi). Sospetto che ci sia un problema di matematica qui. –
@RobertHarvey: Oh, forse le parentesi errate nel cast? –