Measuring execution time of a function in C++

后端 未结 11 684
小鲜肉
小鲜肉 2020-11-22 12:59

I want to find out how much time a certain function takes in my C++ program to execute on Linux. Afterwards, I want to make a speed comparison . I saw sever

相关标签:
11条回答
  • 2020-11-22 13:14

    simple program to find a function execution time taken.

    #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;
    }
    
    0 讨论(0)
  • 2020-11-22 13:15

    Here's a function that will measure the execution time of any function passed as argument:

    #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);
    }
    

    Example usage:

    #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;
    }
    

    Output:

    norm: 15555
    algo: 2976
    
    0 讨论(0)
  • 2020-11-22 13:18

    If you want to safe time and lines of code you can make measuring the function execution time a one line macro:

    a) Implement a time measuring class as already suggested above ( here is my implementation for android):

    class MeasureExecutionTime{
    private:
        const std::chrono::steady_clock::time_point begin;
        const std::string caller;
    public:
        MeasureExecutionTime(const std::string& caller):caller(caller),begin(std::chrono::steady_clock::now()){}
        ~MeasureExecutionTime(){
            const auto duration=std::chrono::steady_clock::now()-begin;
            LOGD("ExecutionTime")<<"For "<<caller<<" is "<<std::chrono::duration_cast<std::chrono::milliseconds>(duration).count()<<"ms";
        }
    };
    

    b) Add a convenient macro that uses the current function name as TAG (using a macro here is important, else __FUNCTION__ will evaluate to MeasureExecutionTime instead of the function you wanto to measure

    #ifndef MEASURE_FUNCTION_EXECUTION_TIME
    #define MEASURE_FUNCTION_EXECUTION_TIME const MeasureExecutionTime measureExecutionTime(__FUNCTION__);
    #endif
    

    c) Write your macro at the begin of the function you want to measure. Example:

     void DecodeMJPEGtoANativeWindowBuffer(uvc_frame_t* frame_mjpeg,const ANativeWindow_Buffer& nativeWindowBuffer){
            MEASURE_FUNCTION_EXECUTION_TIME
            // Do some time-critical stuff 
    }
    

    Which will result int the following output:

    ExecutionTime: For DecodeMJPEGtoANativeWindowBuffer is 54ms
    

    Note that this (as all other suggested solutions) will measure the time between when your function was called and when it returned, not neccesarily the time your CPU was executing the function. However, if you don't give the scheduler any change to suspend your running code by calling sleep() or similar there is no difference between.

    0 讨论(0)
  • 2020-11-22 13:20

    Easy way for older C++, or 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;
    }
    

    Timing precision in seconds is 1.0/CLOCKS_PER_SEC

    0 讨论(0)
  • 2020-11-22 13:24

    Here is an excellent header only class template to measure the elapsed time of a function or any code block:

    #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
    

    Here are some uses of it:

    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;
    }
    

    Since the class is a template we can specify real easily in how we want our time to be measured & displayed. This is a very handy utility class template for doing bench marking and is very easy to use.

    0 讨论(0)
  • 2020-11-22 13:25

    Since none of the provided answers are very accurate or give reproducable results I decided to add a link to my code that has sub-nanosecond precision and scientific statistics.

    Note that this will only work to measure code that takes a (very) short time to run (aka, a few clock cycles to a few thousand): if they run so long that they are likely to be interrupted by some -heh- interrupt, then it is clearly not possible to give a reproducable and accurate result; the consequence of which is that the measurement never finishes: namely, it continues to measure until it is statistically 99.9% sure it has the right answer which never happens on a machine that has other processes running when the code takes too long.

    https://github.com/CarloWood/cwds/blob/master/benchmark.h#L40

    0 讨论(0)
提交回复
热议问题