Coverage Report

Created: 2023-09-25 06:15

/src/cppcheck/lib/timer.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Cppcheck - A tool for static C/C++ code analysis
3
 * Copyright (C) 2007-2023 Cppcheck team.
4
 *
5
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
#include "timer.h"
20
21
#include "utils.h"
22
23
#include <algorithm>
24
#include <iostream>
25
#include <utility>
26
#include <vector>
27
/*
28
    TODO:
29
    - rename "file" to "single"
30
    - add unit tests
31
        - for --showtime (needs input file)
32
        - for Timer* classes
33
 */
34
35
namespace {
36
    using dataElementType = std::pair<std::string, struct TimerResultsData>;
37
    bool more_second_sec(const dataElementType& lhs, const dataElementType& rhs)
38
0
    {
39
0
        return lhs.second.seconds() > rhs.second.seconds();
40
0
    }
41
}
42
43
void TimerResults::showResults(SHOWTIME_MODES mode) const
44
1.36k
{
45
1.36k
    if (mode == SHOWTIME_MODES::SHOWTIME_NONE || mode == SHOWTIME_MODES::SHOWTIME_FILE_TOTAL)
46
1.36k
        return;
47
48
0
    std::cout << std::endl;
49
0
    TimerResultsData overallData;
50
51
0
    std::vector<dataElementType> data;
52
0
    {
53
0
        std::lock_guard<std::mutex> l(mResultsSync);
54
0
        data.reserve(mResults.size());
55
0
        data.insert(data.begin(), mResults.cbegin(), mResults.cend());
56
0
    }
57
0
    std::sort(data.begin(), data.end(), more_second_sec);
58
59
0
    size_t ordinal = 1; // maybe it would be nice to have an ordinal in output later!
60
0
    for (std::vector<dataElementType>::const_iterator iter=data.cbegin(); iter!=data.cend(); ++iter) {
61
0
        const double sec = iter->second.seconds();
62
0
        const double secAverage = sec / (double)(iter->second.mNumberOfResults);
63
0
        bool hasParent = false;
64
0
        {
65
            // Do not use valueFlow.. in "Overall time" because those are included in Tokenizer already
66
0
            if (startsWith(iter->first,"valueFlow"))
67
0
                hasParent = true;
68
69
            // Do not use inner timers in "Overall time"
70
0
            const std::string::size_type pos = iter->first.rfind("::");
71
0
            if (pos != std::string::npos)
72
0
                hasParent = std::any_of(data.cbegin(), data.cend(), [iter,pos](const dataElementType& d) {
73
0
                    return d.first.size() == pos && iter->first.compare(0, d.first.size(), d.first) == 0;
74
0
                });
75
0
        }
76
0
        if (!hasParent)
77
0
            overallData.mClocks += iter->second.mClocks;
78
0
        if ((mode != SHOWTIME_MODES::SHOWTIME_TOP5) || (ordinal<=5)) {
79
0
            std::cout << iter->first << ": " << sec << "s (avg. " << secAverage << "s - " << iter->second.mNumberOfResults  << " result(s))" << std::endl;
80
0
        }
81
0
        ++ordinal;
82
0
    }
83
84
0
    const double secOverall = overallData.seconds();
85
0
    std::cout << "Overall time: " << secOverall << "s" << std::endl;
86
0
}
87
88
void TimerResults::addResults(const std::string& str, std::clock_t clocks)
89
0
{
90
0
    std::lock_guard<std::mutex> l(mResultsSync);
91
92
0
    mResults[str].mClocks += clocks;
93
0
    mResults[str].mNumberOfResults++;
94
0
}
95
96
Timer::Timer(std::string str, SHOWTIME_MODES showtimeMode, TimerResultsIntf* timerResults)
97
    : mStr(std::move(str))
98
    , mTimerResults(timerResults)
99
    , mStart(std::clock())
100
    , mShowTimeMode(showtimeMode)
101
    , mStopped(showtimeMode == SHOWTIME_MODES::SHOWTIME_NONE || showtimeMode == SHOWTIME_MODES::SHOWTIME_FILE_TOTAL)
102
39.4k
{}
103
104
Timer::Timer(bool fileTotal, std::string filename)
105
    : mStr(std::move(filename))
106
    , mStopped(!fileTotal)
107
1.36k
{}
108
109
Timer::~Timer()
110
40.8k
{
111
40.8k
    stop();
112
40.8k
}
113
114
void Timer::stop()
115
40.8k
{
116
40.8k
    if ((mShowTimeMode != SHOWTIME_MODES::SHOWTIME_NONE) && !mStopped) {
117
0
        const std::clock_t end = std::clock();
118
0
        const std::clock_t diff = end - mStart;
119
120
0
        if (mShowTimeMode == SHOWTIME_MODES::SHOWTIME_FILE) {
121
0
            const double sec = (double)diff / CLOCKS_PER_SEC;
122
0
            std::cout << mStr << ": " << sec << "s" << std::endl;
123
0
        } else if (mShowTimeMode == SHOWTIME_MODES::SHOWTIME_FILE_TOTAL) {
124
0
            const double sec = (double)diff / CLOCKS_PER_SEC;
125
0
            std::cout << "Check time: " << mStr << ": " << sec << "s" << std::endl;
126
0
        } else {
127
0
            if (mTimerResults)
128
0
                mTimerResults->addResults(mStr, diff);
129
0
        }
130
0
    }
131
132
40.8k
    mStopped = true;
133
40.8k
}