1 /*
2     This file is part of Quick Qanava library.
3 
4     Copyright (C) 2008-2015 Benoit AUTHEMAN
5 
6     This program is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 //-----------------------------------------------------------------------------
21 // This file is a part of the GTpo software.
22 //
23 // \file	qtpo_benchmarks.cpp
24 // \author	benoit@qanava.org
25 // \date	2016 03 26
26 //-----------------------------------------------------------------------------
27 
28 // STD headers
29 #include <list>
30 #include <memory>
31 #include <iostream>
32 
33 // GTpo headers
34 #include <GTpo>
35 #include "../src/algorithm.h"
36 #include "../src/generator.h"
37 
38 // Google Benchmark
39 #include <benchmark/benchmark.h>
40 
41 /*
42  * Available benchmarks:
43  * --benchmark_report_aggregates_only={true|false}
44  *
45  *
46  *
47  */
48 
49 
50 struct config_raw final :  public gtpo::config<config_raw>
51 {
52 };
53 using graph_raw = gtpo::graph<config_raw>;
54 
55 struct config_adjacent final :  public gtpo::config<config_adjacent>
56 {
57     using graph_behaviours = std::tuple< gtpo::graph_group_adjacent_edges_behaviour<config_adjacent> >;
58     using group_behaviours = std::tuple< gtpo::group_adjacent_edges_behaviour<config_adjacent> >;
59     using node_behaviours = std::tuple< >;
60 };
61 using graph_adjacent = gtpo::graph<config_adjacent>;
62 
63 
64 struct config_no_dynamic final :  public gtpo::config<config_no_dynamic>
65 {
66     using final_config = config_no_dynamic;
67     using graph_behaviours = std::tuple< >;
68     using group_behaviours = std::tuple< >;
69     using node_behaviours = std::tuple< >;
70 };
71 using graph_no_dynamic = gtpo::graph<config_no_dynamic>;
72 
73 
74 using graph_complete = gtpo::graph<>;
75 
76 namespace impl {  // ::impl
77 
78 template < typename graph_t >
benchmark(graph_t & g)79 void    benchmark(graph_t& g) {
80     auto n1 = g.create_node();
81     auto n2 = g.create_node();
82     auto e = g.create_edge( n1, n2 );
83 
84     auto g1 = g.create_group();
85     g.group_node(n1, g1);
86     g.ungroup_node(n1, g1);
87 
88     g.remove_group(g1);
89     g.remove_edge(e);
90     g.remove_node(n2);
91     g.remove_node(n1);
92 }
93 
94 } // :impl
95 
BM_GraphRaw(benchmark::State & state)96 static void BM_GraphRaw(benchmark::State& state)
97 {
98     graph_raw g;
99     for (auto _ : state) {
100         impl::benchmark(g);
101     }
102 }
103 
BM_GraphAdjacent(benchmark::State & state)104 static void BM_GraphAdjacent(benchmark::State& state)
105 {
106     graph_adjacent g;
107     for (auto _ : state) {
108         impl::benchmark(g);
109     }
110 }
111 
112 
BM_GraphNoDynamic(benchmark::State & state)113 static void BM_GraphNoDynamic(benchmark::State& state)
114 {
115     graph_no_dynamic g;
116     for (auto _ : state) {
117         impl::benchmark(g);
118     }
119 }
120 
BM_GraphComplete(benchmark::State & state)121 static void BM_GraphComplete(benchmark::State& state)
122 {
123     graph_complete g;
124     for (auto _ : state) {
125         impl::benchmark(g);
126     }
127 }
128 
129 BENCHMARK(BM_GraphRaw);
130 BENCHMARK(BM_GraphAdjacent);
131 BENCHMARK(BM_GraphNoDynamic);
132 BENCHMARK(BM_GraphComplete);
133 
134 
135 static std::vector<std::unique_ptr<gtpo::graph<>>>  bin_trees;
136 
BM_linearize_dfs_on_tree(benchmark::State & state)137 static void BM_linearize_dfs_on_tree(benchmark::State& state)
138 {
139     const auto g = bin_trees[state.range(0)].get();
140     for (auto _ : state) {
141         auto r = gtpo::linearize_dfs(*g);
142     }
143 }
BM_linearize_tree_dfs_rec(benchmark::State & state)144 static void BM_linearize_tree_dfs_rec(benchmark::State& state)
145 {
146     const auto g = bin_trees[state.range(0)].get();
147     for (auto _ : state) {
148         auto r = gtpo::linearize_tree_dfs_rec(*g);
149     }
150 }
__anon08d448270102(const std::vector<double>& v) 151 BENCHMARK(BM_linearize_dfs_on_tree)->ComputeStatistics("max", [](const std::vector<double>& v) -> double {
152     return *(std::max_element(std::begin(v), std::end(v)));
153   })->ComputeStatistics("min", [](const std::vector<double>& v) -> double {
154     return *(std::min_element(std::begin(v), std::end(v)));
155   })->DenseRange(0, 14, 1);
__anon08d448270302(const std::vector<double>& v) 156 BENCHMARK(BM_linearize_tree_dfs_rec)->ComputeStatistics("max", [](const std::vector<double>& v) -> double {
157     return *(std::max_element(std::begin(v), std::end(v)));
158   })->ComputeStatistics("min", [](const std::vector<double>& v) -> double {
159     return *(std::min_element(std::begin(v), std::end(v)));
160   })->DenseRange(0, 14, 1);
161 
main(int argc,char ** argv)162 int main(int argc, char** argv) {
163     // Generate CSV with following command:
164     // ./gtpo_benchmarks --benchmark_filter=BM_linearize  --benchmark_report_aggregates_only=true --benchmark_repetitions=4 --benchmark_out_format=csv  --benchmark_out=linearize_dfs_tree.csv
165 
166     // Generate candidate trees
167     for ( int depth = 0; depth < 15; depth++ ) {
168         auto t = std::make_unique<gtpo::graph<>>();
169         gtpo::complete_tree_rec(*t, depth, 2);
170         bin_trees.emplace_back(std::move(t));
171     }
172 
173     benchmark::Initialize(&argc, argv);
174     benchmark::RunSpecifiedBenchmarks();
175 }
176 
177