forked from jakaspeh/concurrency
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbenchmark.cpp
More file actions
156 lines (119 loc) · 4.46 KB
/
Copy pathbenchmark.cpp
File metadata and controls
156 lines (119 loc) · 4.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <iostream>
#include <iomanip>
#include <limits>
#include <vector>
#include <numeric>
#include <algorithm>
#include <chrono>
#include <thread>
#include <future>
template <typename TimeT = std::chrono::microseconds>
class Benchmark
{
public:
Benchmark(int num_iterations=100, int throw_away=0)
: m_num_iter(num_iterations),
m_throw_away(throw_away),
m_times(),
m_mean(),
m_st_dev()
{ }
template <typename Fun, typename... Args>
std::vector< typename std::result_of< Fun(Args...) >::type >
benchmark(Fun&& fun, Args&&... args)
{
using result_t = typename std::result_of< Fun(Args...) >::type;
std::vector< result_t > results;
m_times.clear();
auto n = m_num_iter + m_throw_away;
for (auto i = 0; i != n; i++)
{
auto pair = measure_execution(std::forward<Fun>(fun),
std::forward<Args>(args)...);
m_times.push_back(pair.first);
results.push_back(pair.second);
}
compute_mean();
compute_st_dev();
return results;
}
typename TimeT::rep mean() const
{
return m_mean;
}
typename TimeT::rep standard_deviation() const
{
return m_st_dev;
}
private:
template <typename Fun, typename... Args>
static std::pair< typename TimeT::rep, typename std::result_of< Fun(Args...) >::type >
measure_execution(Fun&& fun, Args&&... args)
{
auto t1 = std::chrono::steady_clock::now();
auto result = std::forward<Fun>(fun)(std::forward<Args>(args)...);
auto t2 = std::chrono::steady_clock::now();
auto time = std::chrono::duration_cast<TimeT>( t2 - t1 ).count();
return std::make_pair(time, result);
}
void compute_mean()
{
auto sum = std::accumulate(m_times.begin() + m_throw_away, m_times.end(), 0);
m_mean = sum / m_num_iter;
}
void compute_st_dev()
{
std::vector<typename TimeT::rep> diff(m_num_iter);
std::transform(m_times.begin() + m_throw_away, m_times.end(), diff.begin(),
[this](typename TimeT::rep t) {return t - this->m_mean;});
auto sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), 0);
m_st_dev = std::sqrt(sq_sum / m_num_iter);
}
int m_num_iter;
int m_throw_away;
std::vector<typename TimeT::rep> m_times;
typename TimeT::rep m_mean;
typename TimeT::rep m_st_dev;
};
int main()
{
auto n = 1000000;
std::vector<int> vector(n, 1);
auto t1 = std::chrono::steady_clock::now();
auto sum = std::accumulate(vector.begin(), vector.end(), 0);
auto t2 = std::chrono::steady_clock::now();
using nano_s = std::chrono::nanoseconds;
using micro_s = std::chrono::microseconds;
using milli_s = std::chrono::milliseconds;
using seconds = std::chrono::seconds;
using minutes = std::chrono::minutes;
using hours = std::chrono::hours;
auto d_nano = std::chrono::duration_cast<nano_s>( t2 - t1 ).count();
auto d_micro = std::chrono::duration_cast<micro_s>( t2 - t1 ).count();
auto d_milli = std::chrono::duration_cast<milli_s>( t2 - t1 ).count();
auto d_s = std::chrono::duration_cast<seconds>( t2 - t1 ).count();
auto d_m = std::chrono::duration_cast<minutes>( t2 - t1 ).count();
auto d_h = std::chrono::duration_cast<hours>( t2 - t1 ).count();
std::cout << "sum: " << sum << "\n"
<< "d_nano: " << d_nano << "\n"
<< "d_micro: " << d_micro << "\n"
<< "d_milli: " << d_milli << "\n"
<< "d_s: " << d_s << "\n"
<< "d_m: " << d_m << "\n"
<< "d_h: " << d_h << "\n"
<< std::endl;
for (auto numEl = n; numEl != 11 * n; numEl += n)
{
Benchmark<> benchmark;
std::vector<int> vector(numEl, 1);
using Iterator = decltype(vector.begin());
auto results = benchmark.benchmark(std::accumulate< Iterator, int>,
vector.begin(), vector.end(), 0);
std::cout << "#elements: " << std::setw(9) << numEl << " "
<< " mean: " << std::setw(8) << benchmark.mean()
<< " st. dev: : " << std::setw(8)
<< benchmark.standard_deviation()
<< std::endl;
}
return 0;
}