C++ Замер производительности
От: VNG Беларусь https://organicmaps.app/
Дата: 28.01.06 18:10
Оценка: 6 (1)
Написаны макросы для замера производительности отдельных участков кода и вывода результатов в файл. Используется функция QueryPerformanceCounter.
Выводится:
— общее время выполнения участка кода
— количество раз, которое выполнялся участок кода
— среднее время работы участка кода

Пример использования:
DECLARE_PERFORMANCE_FILE_STREAM(F:\\finish_dos_point_perf.log, perfFile);

DECLARE_PERFORMANCE_CHECKER(1, perfFile);
START_PERFORMANCE_CHECK(1);
// участок номер 1 для замера
FINISH_PERFORMANCE_CHECK(1);

DECLARE_PERFORMANCE_CHECKER(2, perfFile);
START_PERFORMANCE_CHECK(2);
// участок номер 2 для замера
FINISH_PERFORMANCE_CHECK(2);


Собственно, сама реализация.
#pragma once

#include <fstream>
#include <string>

namespace performance 
{
    /// Класс замера времени.
    class timer
    {
        LARGE_INTEGER m_start;

    public:

        inline void start() { QueryPerformanceCounter(&m_start); }

        inline double finish()
        {
            LARGE_INTEGER finish;
            QueryPerformanceCounter(&finish);
            LARGE_INTEGER freq;
            QueryPerformanceFrequency(&freq);
            return double(finish.QuadPart - m_start.QuadPart) / double(freq.QuadPart);
        }

        template <class TStream> void finish_output(TStream & out)
        {
            out << finish() << std::endl;
        }
    };

    /// Класс замера производительности многократного выполнения некого куска кода.
    /// Накапливает статистику по времени ее выполнения и количества выполнения.
    class instruction_checker
    {
        timer m_timer;

        class instruction_info
        {
            double m_time;
            size_t m_count;

        public:

            instruction_info() : m_time(0.0), m_count(0) {}
            void add_time(double time) { m_time += time; }
            void inc_count() { ++m_count; }

            inline double get_time() const { return m_time; }
            inline size_t get_count() const { return m_count; }
            inline double get_average_time() const { return m_time / double(m_count); }
        } m_info;

    public:

        inline void start() { m_timer.start(); }
        inline void finish()
        {
            m_info.add_time(m_timer.finish());
            m_info.inc_count();
        }

        inline double get_time() const { return m_info.get_time(); }
        inline size_t get_count() const { return m_info.get_count(); }
        inline double get_average_time() const { return m_info.get_average_time(); }
    };

    /// Класс - guard для замера многократно-вызываемого участка кода.
    /// Имеет интерфейс класса performance_instruction_checker и дополнительно
    /// в деструкторе выводит в поток накопленную информацию.
    /// Должен использоваться как статический экземпляр в функции.
    class stream_guard
    {
        instruction_checker m_checker;
        int m_instructionNumber;
        std::ofstream & m_outFile;
    public:
        stream_guard(int instructionNumber, std::ofstream & outFile)
            : m_instructionNumber(instructionNumber), m_outFile(outFile)
        {
        }
        inline void start() { m_checker.start(); }
        inline void finish() { m_checker.finish(); }
        ~stream_guard()
        {
            m_outFile << "Instruction number = " << m_instructionNumber << std::endl;
            m_outFile << "Hole time = " << m_checker.get_time() << std::endl;
            m_outFile << "Call count = " << static_cast<unsigned int>(m_checker.get_count()) << std::endl;
            m_outFile << "Average time = " << m_checker.get_average_time() << std::endl;
            m_outFile << "===============================================" << std::endl;
        }
    };
}

/// Макрос задания файла для накопления статистики
#define DECLARE_PERFORMANCE_FILE_STREAM(fileName, varName)    \
    static std::ofstream varName(#fileName)

/// Макрос задания статического экземпляра checkera
#define DECLARE_PERFORMANCE_CHECKER(index, outFile)    \
    static performance::stream_guard performance_checker_##index(index, outFile)

/// Макрос начала замера
#define START_PERFORMANCE_CHECK(index)    \
    performance_checker_##index.start()

/// Макрос конца замера
#define FINISH_PERFORMANCE_CHECK(index)    \
    performance_checker_##index.finish()
... << RSDN@Home 1.1.4 stable rev. 510>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.