Измерение времени выполнения функции в C++


Я хочу узнать, сколько времени занимает определенная функция в моей программе C++ для выполнения на Linux. После этого, я хочу сделать сравнение скорости . Я видел несколько раз, но закончилось это с разгона. Хроно:

process_user_cpu_clock, captures user-CPU time spent by the current process

теперь мне не ясно, если я использую вышеуказанную функцию, я получу единственное время, которое процессор потратил на эту функцию?

во-вторых, я не смог найти ни одного примера использования вышеуказанной функции. Может кто-нибудь, пожалуйста, помогите мне, как используйте вышеуказанную функцию?

P. S: прямо сейчас, я использую std::chrono::system_clock::now() чтобы получить время в секундах, но это дает мне разные результаты из-за разной нагрузки на процессор каждый раз.

5 66

5 ответов:

Это очень простой в использовании метод в C++11. Вы должны использовать std::chrono::high_resolution_clock С <chrono> заголовок.

используйте его так:

#include <iostream>
#include <chrono>

using namespace std;
using namespace std::chrono;

void function()
{
    long long number = 0;

    for( long long i = 0; i != 2000000; ++i )
    {
       number += 5;
    }
}

int main()
{
    high_resolution_clock::time_point t1 = high_resolution_clock::now();
    function();
    high_resolution_clock::time_point t2 = high_resolution_clock::now();

    auto duration = duration_cast<microseconds>( t2 - t1 ).count();

    cout << duration;
    return 0;
}

это будет измерять продолжительность функции.

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

вот функция, которая будет измерять время выполнения любой функции, переданной в качестве аргумента:

#include <chrono>
#include <utility>

typedef std::chrono::high_resolution_clock::time_point TimeVar;

#define duration(a) std::chrono::duration_cast<std::chrono::nanoseconds>(a).count()
#define timeNow() std::chrono::high_resolution_clock::now()

template<typename F, typename... Args>
double funcTime(F func, Args&&... args){
    TimeVar t1=timeNow();
    func(std::forward<Args>(args)...);
    return duration(timeNow()-t1);
}

пример использования:

#include <iostream>
#include <algorithm>

typedef std::string String;

//first test function doing something
int countCharInString(String s, char delim){
    int count=0;
    String::size_type pos = s.find_first_of(delim);
    while ((pos = s.find_first_of(delim, pos)) != String::npos){
        count++;pos++;
    }
    return count;
}

//second test function doing the same thing in different way
int countWithAlgorithm(String s, char delim){
    return std::count(s.begin(),s.end(),delim);
}


int main(){
    std::cout<<"norm: "<<funcTime(countCharInString,"precision=10",'=')<<"\n";
    std::cout<<"algo: "<<funcTime(countWithAlgorithm,"precision=10",'=');
    return 0;
}

выход:

norm: 15555
algo: 2976

простая программа для поиска времени выполнения функции.

#include <iostream>
#include <ctime> // time_t
#include <cstdio>

void function()
{
     for(long int i=0;i<1000000000;i++)
     {
        // do nothing
     }
}

int main()
{

time_t begin,end; // time_t is a datatype to store time values.

time (&begin); // note time before execution
function();
time (&end); // note time after execution

double difference = difftime (end,begin);
printf ("time taken for function() %.2lf seconds.\n", difference );

return 0;
}

простой способ для старых C++ или C:

#include <time.h> // includes clock_t and CLOCKS_PER_SEC

int main() {

    clock_t start, end;

    start = clock();
    // ...code to measure...
    end = clock();

    double duration_sec = double(end-start)/CLOCKS_PER_SEC;
    return 0;
}

точность синхронизации в секундах 1.0/CLOCKS_PER_SEC

вот отличный заголовок только шаблон класса для измерения времени функции или какого-либо блока кода:

#ifndef EXECUTION_TIMER_H
#define EXECUTION_TIMER_H

template<class Resolution = std::chrono::milliseconds>
class ExecutionTimer {
public:
    using Clock = std::conditional_t<std::chrono::high_resolution_clock::is_steady,
                                     std::chrono::high_resolution_clock,
                                     std::chrono::steady_clock>;
private:
    const Clock::time_point mStart = Clock::now();

public:
    ExecutionTimer() = default;
    ~ExecutionTimer() {
        const auto end = Clock::now();
        std::ostringstream strStream;
        strStream << "Destructor Elapsed: "
                  << std::chrono::duration_cast<Resolution>( end - mStart ).count()
                  << std::endl;
        std::cout << strStream.str() << std::endl;
    }    

    inline void stop() {
        const auto end = Clock::now();
        std::ostringstream strStream;
        strStream << "Stop Elapsed: "
                  << std::chrono::duration_cast<Resolution>(end - mStart).count()
                  << std::endl;
        std::cout << strStream.str() << std::endl;
    }

}; // ExecutionTimer

#endif // EXECUTION_TIMER_H

вот некоторые его применения:

int main() {
    { // empty scope to display ExecutionTimer's destructor's message
         // displayed in milliseconds
         ExecutionTimer<std::chrono::milliseconds> timer;

         // function or code block here

         timer.stop();

    } 

    { // same as above
        ExecutionTimer<std::chrono::microseconds> timer;

        // code block here...

        timer.stop();
    }

    {  // same as above
       ExecutionTimer<std::chrono::nanoseconds> timer;

       // code block here...

       timer.stop();

    }

    {  // same as above
       ExecutionTimer<std::chrono::seconds> timer;

       // code block here...

       timer.stop();

    }              

    return 0;
}

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