Предположим, что у меня есть несколько алгоритмов для проверки следующим образом.
void AlgoA(int x)
{
// critical operations go here
}
void AlgoB(int x, int y)
{
// critical operations go here
}
Первый подход
Я определяю Timer
, который принимает указатель на функцию без параметров.
void Timer(void (*f)(), unsigned short N = 1)
{
vector<unsigned long long> results;
for (unsigned short i = 0; i < N; i++)
{
chrono::steady_clock::time_point begin = chrono::steady_clock::now();
f();
chrono::steady_clock::time_point end = chrono::steady_clock::now();
unsigned long long interval = chrono::duration_cast<chrono::microseconds>(end - begin).count();
results.push_back(interval);
cout << "Elapsed time: " << interval << std::endl;
}
unsigned long long sum = 0;
for (unsigned long long x : results)
sum += x;
cout << "Average: " << sum / results.size() << endl;
}
Обертки необходимы для подготовки входных данных.
void DoA()
{
int x;
// preparing x goes here
AlgoA(x);
}
void DoB()
{
int x, y;
// preparing x and y goes here
AlgoB(x, y);
}
void main()
{
Timer(DoA);
Timer(DoB);
}
Минусы: Timer
также подсчитывает время, затраченное на подготовку входных данных.
Плюсы: общее Timer
для многих алгоритмов тестирования.
Второй подход
Мне нужно написать 2 таймера, каждый для алгоритма тестирования.
void TimerA(void (*f)(int), int x, unsigned short N = 1)
{
vector<unsigned long long> results;
for (unsigned short i = 0; i < N; i++)
{
chrono::steady_clock::time_point begin = chrono::steady_clock::now();
f(x);
chrono::steady_clock::time_point end = chrono::steady_clock::now();
unsigned long long interval = chrono::duration_cast<chrono::microseconds>(end - begin).count();
results.push_back(interval);
cout << "Elapsed time: " << interval << std::endl;
}
unsigned long long sum = 0;
for (unsigned long long x : results)
sum += x;
cout << "Average: " << sum / results.size() << endl;
}
void TimerB(void (*f)(int, int), int x, int y, unsigned short N = 1)
{
vector<unsigned long long> results;
for (unsigned short i = 0; i < N; i++)
{
chrono::steady_clock::time_point begin = chrono::steady_clock::now();
f(x, y);
chrono::steady_clock::time_point end = chrono::steady_clock::now();
unsigned long long interval = chrono::duration_cast<chrono::microseconds>(end - begin).count();
results.push_back(interval);
cout << "Elapsed time: " << interval << std::endl;
}
unsigned long long sum = 0;
for (unsigned long long x : results)
sum += x;
cout << "Average: " << sum / results.size() << endl;
}
void main()
{
int x;
// preparing x goes here.
TimerA(AlgoA, x);
int y;
// preparing y goes here.
TimerB(AlgoB, x, y);
}
Плюсы: таймеры учитывают только критические операции.
Минусы: несколько таймеров, каждый для одногоalgo to test.
Вопрос
Можно ли просто создать один Timer
, но он не должен считать время, необходимое для подготовки входных данных?
Редактировать:
Входные данные на самом деле не просто int
, а struct
и т. Д., Которые могут быть получены из зависимого от времени ввода-вывода.