Backstory
(Вы можете пропустить. Полезно, если вы хотите расширить и принять мой подход.)
Я пытаюсь расширить библиотеку отладки, которую я создал, чтобы иметь возможность проводить ненавязчивый бенчмаркинги отладка.Пока это выглядит примерно так, однако я открыт для реконструкции.Это похоже на то, что я использовал для гибкой отладки типов:
#define BENCH(FUNC,N)CT::bench(#FUNC,FUNC,N,__FILE__,__LINE__,__PRETTY_FUNCTION__)
// #FUNC is a string of the code for the function placed in the macro
// FUNC is the function. How it should be captured, I am not sure yet.
// N Should be the number of times you wish to run the captured function
// __FILE__, __LINE__, __PRETTY_FUNCTION__ are GCC predefined macros
// Used for easily locating the code that is generating the output.
template <typename First> // Problem: Ensure only functions used as arguments?
static First bench(const QString expression,
First &&type, // This is the type. Needed for the return.
quint64 repeatN, // Negative repeats make no sense.
const QString &_file,
const int &_line,
const QString &_pretty_function)
{
QString typeName = QConsoleToolkit::demangle(typeid(type).name());
int initial(-1); // Time required to execute function first time
int average(-1); // Average execution time.
for (int i=0; i < repeatN; i++) {
// *
// *
// No idea how to do this.
// Please help.
// *
// *
}
QTextStream(stdout)
<< "Benchmark: " << typeName
<< "\t" << expression
<< "\t" << _pretty_function
<< "\t" << _file
<< ":" << _line << endl
<< " Repeat: " << QString::number(repeatN) << endl
<< "Initial: " << QString::number(initial) << endl
<< "Average: " << QString::number(average) << endl;
// Unsure if this will work with void
return std::forward<First>(type);
}
// Returns string for type
QString CT::demangle(const QString &name)
{
int status;
std::unique_ptr<char, void(*)(void*)> res {
abi::__cxa_demangle(name.toLatin1(), NULL, NULL, &status),
std::free
};
return {(status==0) ? QLatin1String(res.get()) : name};
}
Актуальный вопрос
Возьмите следующий код:
void MyClass::foo()
{
//dostuff
}
QString MyClass::funString()
{
return "The quick brown fox jumps over the lazy dog";
}
void MyClass::bar()
{
BENCH(foo(), 1000);
QString s = BENCH(funString(),2000);
QTextStream(stdout) << s << endl;
}
Myцель состоит в том, чтобы MyClass::bar()
вывел это: (случайные числа составлены для начального и среднего значения)
Benchmark: void foo() void MyClass::bar() /home/akiva/myclass.cpp:31
Repeat: 1000
Initial: 2523
Average: 1234
Benchmark: QString funString() void MyClass::bar() /home/akiva/myclass.cpp:32
Repeat: 2000
Initial: 5003
Average: 4025
The quick brown fox jumps over the lazy dog
Таким образом, как я могу сделать так, чтобы макрос BENCH()
мог принимать любой тип функции,запускать его N
раз, сравнивая, сколько времени занимает каждая итерация и возвращает ли оно первое начальное значение, полученное при первом запуске?
Оно не может быть навязчивым, что делает эту строку возможной:
QString s = BENCH(funString(),2000);