профилирование — совокупное время нахождения блоков кода в переполнении стека

У меня большая кодовая база, и я хочу вручную добавить несколько таймеров для профилирования некоторых разделов кода.
Некоторые из этих разделов находятся в цикле, поэтому я хотел бы объединить все время, проведенное на стене для каждой итерации.

Что я хотел бы сделать в псевдокоде Pythonic:

time_step_1 = 0
time_step_2 = 0
for pair in pairs:

start_step_1 = time.now()
run_step_1(pair)
time_step_1 += start_step_1 - time.now()

start_step_2 = time.now()
run_step_2(pair)
time_step_2 += start_step_2 - time.now()

print("Time spent in step 1", time_step_1)
print("Time spent in step 2", time_step_2)

Есть ли в C ++ библиотека для этого?
В противном случае вы бы порекомендовали использовать boost::timerсоздать карту таймеров, а затем возобновить и остановиться на каждой итерации?

0

Решение

Не очень продвинутый, но для базового измерения времени, вы можете использовать std::chrono библиотека, в частности, std::chrono::high_resolution_clock — часы
с наименьшим периодом тиков (= наибольшей точностью), обеспечиваемым реализацией.

Для более простого измерения времени я использовал классы RAII, подобные этому:

#include <chrono>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <string>

class TimeMeasureGuard {
public:
using clock_type = std::chrono::high_resolution_clock;

private:
const std::string m_testName;
std::ostream& m_os;

clock_type::time_point started_at;
clock_type::time_point ended_at;

public:
TimeMeasureGuard(const std::string& testName, std::ostream& os = std::cerr)
: m_testName(testName), m_os(os)
{
started_at = clock_type::now();
}

~TimeMeasureGuard()
{
ended_at = clock_type::now();

// Get duration
const auto duration = ended_at - started_at;

// Get duration in nanoseconds
const auto durationNs = std::chrono::nanoseconds(duration).count();
// ...or in microseconds:
const auto durationUs
= std::chrono::duration_cast<std::chrono::microseconds>(duration).count();

// Report total run time into 'm_os' stream
m_os << "[Test " << std::quoted(m_testName) << "]: Total run time: "<< durationNs << " ns, " << "or: " << durationUs << " us" << std::endl;
}
};

Конечно, это очень простой класс, который заслуживает нескольких улучшений, прежде чем использовать его для реального измерения.

Вы можете использовать этот класс как:

std::uint64_t computeSquares()
{
std::uint64_t interestingNumbers = 0;
{
auto time_measurement = TimeMeasureGuard("Test1");

for (std::uint64_t x = 0; x < 1'000; ++x) {
for (std::uint64_t y = 0; y < 1'000; ++y) {
if ((x * y) % 42 == 0)
++interestingNumbers;
}
}
}
return interestingNumbers;
}

int main()
{
std::cout << "Computing all x * y, where 'x' and 'y' are from 1 to 1'000..."<< std::endl;
const auto res = computeSquares();
std::cerr << "Interesting numbers found: " << res << std::endl;

return 0;
}

И вывод:

Computing all x * y, where 'x' and 'y' are from 1 to 1'000...
[Test "Test1"]: Total run time: 6311371 ns, or: 6311 us
Interesting numbers found: 111170

Для простых случаев измерения времени это может быть проще, чем использование
целая библиотека таймеров, и это всего лишь несколько строк кода, вы не
нужно включить много заголовков.

1

Другие решения

Других решений пока нет …