Uso la mia versione della funzione time_it
di Python. Il vantaggio di questa funzione è che ripete un calcolo tante volte quanto è necessario per ottenere risultati significativi. Se il calcolo è molto veloce, verrà ripetuto molte volte. Alla fine si ottiene il tempo medio di tutte le ripetizioni. Esso non utilizza alcuna funzionalità non standard:
#include <ctime>
double clock_diff_to_sec(long clock_diff)
{
return double(clock_diff)/CLOCKS_PER_SEC;
}
template<class Proc>
double time_it(Proc proc, int N=1) // returns time in microseconds
{
std::clock_t const start = std::clock();
for(int i = 0; i < N; ++i)
proc();
std::clock_t const end = std::clock();
if(clock_diff_to_sec(end - start) < .2)
return time_it(proc, N * 5);
return clock_diff_to_sec(end - start) * (1e6/N);
}
Il seguente esempio utilizza la funzione time_it
per misurare le prestazioni di diversi contenitori STL:
void dummy_op(int i)
{
if(i == -1)
std::cout << i << "\n";
}
template<class Container>
void test(Container const & c)
{
std::for_each(c.begin(), c.end(), &dummy_op);
}
template<class OutIt>
void init(OutIt it)
{
for(int i = 0; i < 1000; ++i)
*it = i;
}
int main(int argc, char ** argv)
{
{
std::vector<int> c;
init(std::back_inserter(c));
std::cout << "vector: "
<< time_it(boost::bind(&test<std::vector<int> >, c)) << "\n";
}
{
std::list<int> c;
init(std::back_inserter(c));
std::cout << "list: "
<< time_it(boost::bind(&test<std::list<int> >, c)) << "\n";
}
{
std::deque<int> c;
init(std::back_inserter(c));
std::cout << "deque: "
<< time_it(boost::bind(&test<std::deque<int> >, c)) << "\n";
}
{
std::set<int> c;
init(std::inserter(c, c.begin()));
std::cout << "set: "
<< time_it(boost::bind(&test<std::set<int> >, c)) << "\n";
}
{
std::tr1::unordered_set<int> c;
init(std::inserter(c, c.begin()));
std::cout << "unordered_set: "
<< time_it(boost::bind(&test<std::tr1::unordered_set<int> >, c)) << "\n";
}
}
Nel caso qualcuno è curioso ecco l'uscita I get (compilato con VS2008 nella modalità di rilascio):
vettore: 8,7168
lista: 27,776
deque: 91,52
set: 103,04
unordered_set: 29.76
fa GetTickCount() utilizzare QueryPerformanceCounter() sotto il cappuccio o? – Mithrax
Che io non sappia. Ho aggiunto un collegamento alla pagina GetTickCount() e sembra che tu abbia altre opzioni, probabilmente migliori, basate su ciò che è presente. – John
No. GetTickCount() non è accurato. Se si desidera un conteggio accurato, è necessario utilizzare QueryPerformanceCounter() (EDIT: per inaccurato intendo +/- 10 ms) –