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
|
// Copyright (C) 2016-2018 T. Zachary Laine
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/yap/expression.hpp>
#include <chrono>
#include <iostream>
#include <benchmark/benchmark.h>
template<typename T>
using term = boost::yap::terminal<boost::yap::expression, T>;
namespace yap = boost::yap;
namespace bh = boost::hana;
//[ arithmetic_perf_decls
namespace user {
struct number
{
double value;
friend number operator+(number lhs, number rhs)
{
return number{lhs.value + rhs.value};
}
friend number operator*(number lhs, number rhs)
{
return number{lhs.value * rhs.value};
}
};
}
//]
double get_noise()
{
auto const start_time = std::chrono::high_resolution_clock::now();
auto const start_time_ns =
std::chrono::time_point_cast<std::chrono::nanoseconds>(start_time);
return 1.0 * start_time_ns.time_since_epoch().count();
}
user::number g_a{get_noise()};
user::number g_x{get_noise()};
user::number g_y{get_noise()};
//[ arithmetic_perf_eval_as_yap_expr
user::number eval_as_yap_expr(user::number a_, user::number x_, user::number y_)
{
term<user::number> a{{a_}};
term<user::number> x{{x_}};
term<user::number> y{{y_}};
auto expr = (a * x + y) * (a * x + y) + (a * x + y);
return yap::evaluate(expr);
}
//]
void BM_eval_as_yap_expr(benchmark::State & state)
{
double d = 0;
while (state.KeepRunning()) {
user::number const n = eval_as_yap_expr(g_a, g_x, g_y);
d += n.value;
}
std::cout << "Sum of doubles=" << d << "\n";
}
//[ arithmetic_perf_eval_as_yap_expr_4x
user::number
eval_as_yap_expr_4x(user::number a_, user::number x_, user::number y_)
{
term<user::number> a{{a_}};
term<user::number> x{{x_}};
term<user::number> y{{y_}};
auto expr = (a * x + y) * (a * x + y) + (a * x + y) +
(a * x + y) * (a * x + y) + (a * x + y) +
(a * x + y) * (a * x + y) + (a * x + y) +
(a * x + y) * (a * x + y) + (a * x + y);
return yap::evaluate(expr);
}
//]
void BM_eval_as_yap_expr_4x(benchmark::State & state)
{
double d = 0;
while (state.KeepRunning()) {
user::number const n = eval_as_yap_expr_4x(g_a, g_x, g_y);
d += n.value;
}
std::cout << "Sum of doubles=" << d << "\n";
}
//[ arithmetic_perf_eval_as_cpp_expr
user::number eval_as_cpp_expr(user::number a, user::number x, user::number y)
{
return (a * x + y) * (a * x + y) + (a * x + y);
}
//]
void BM_eval_as_cpp_expr(benchmark::State & state)
{
double d = 0;
while (state.KeepRunning()) {
user::number const n = eval_as_cpp_expr(g_a, g_x, g_y);
d += n.value;
}
std::cout << "Sum of doubles=" << d << "\n";
}
//[ arithmetic_perf_eval_as_cpp_expr_4x
user::number eval_as_cpp_expr_4x(user::number a, user::number x, user::number y)
{
return (a * x + y) * (a * x + y) + (a * x + y) + (a * x + y) * (a * x + y) +
(a * x + y) + (a * x + y) * (a * x + y) + (a * x + y) +
(a * x + y) * (a * x + y) + (a * x + y);
}
//]
void BM_eval_as_cpp_expr_4x(benchmark::State & state)
{
double d = 0;
while (state.KeepRunning()) {
user::number const n = eval_as_cpp_expr_4x(g_a, g_x, g_y);
d += n.value;
}
std::cout << "Sum of doubles=" << d << "\n";
}
BENCHMARK(BM_eval_as_yap_expr);
BENCHMARK(BM_eval_as_yap_expr_4x);
BENCHMARK(BM_eval_as_cpp_expr);
BENCHMARK(BM_eval_as_cpp_expr_4x);
BENCHMARK_MAIN()
|