1+ #pragma once
2+
3+ #include < benchmark/benchmark.h>
4+ #include " benchmarks_resourses.h"
5+
6+ namespace benchmark {
7+
8+ template <
9+ template <typename , typename , typename > class LRUCacheContainer
10+ >
11+ class LRUCacheBenchmark {
12+ private:
13+ using UserCache = LRUCacheContainer<
14+ User,
15+ indexed_by<
16+ ordered_unique<tag<id_tag>, member<User, int , &User::id>>,
17+ ordered_unique<tag<email_tag>, member<User, std::string, &User::email>>,
18+ ordered_non_unique<tag<name_tag>, member<User, std::string, &User::name>>
19+ >,
20+ std::allocator<User>
21+ >;
22+
23+ static void prepare_cache (UserCache& cache, size_t size) {
24+ for (size_t i = 0 ; i < size; ++i) {
25+ cache.emplace (generator::generate_user ());
26+ }
27+ }
28+
29+ public:
30+ static void BM_GetOperations (benchmark::State& state) {
31+ const size_t cache_size = state.range (0 );
32+ const size_t operations_count = state.range (1 );
33+
34+ UserCache cache (cache_size);
35+ prepare_cache (cache, cache_size);
36+
37+ for (auto _ : state) {
38+ state.PauseTiming ();
39+ std::vector<std::string> names, emails;
40+ std::vector<int > ids;
41+ for (size_t i = 0 ; i < operations_count; ++i) {
42+ names.push_back (generator::generate_name ());
43+ emails.push_back (generator::generate_email ());
44+ ids.push_back (generator::generate_id ());
45+ }
46+ state.ResumeTiming ();
47+
48+ for (size_t i = 0 ; i < operations_count; ++i) {
49+ benchmark::DoNotOptimize (cache.template find <name_tag, std::string>(names[i]));
50+ benchmark::DoNotOptimize (cache.template find <email_tag, std::string>(emails[i]));
51+ benchmark::DoNotOptimize (cache.template find <id_tag, int >(ids[i]));
52+ }
53+ }
54+
55+ state.SetItemsProcessed (state.iterations () * operations_count * 3 );
56+ state.SetComplexityN (cache_size);
57+ }
58+
59+ static void BM_EmplaceOperations (benchmark::State& state) {
60+ const size_t cache_size = state.range (0 );
61+ const size_t operations_count = state.range (1 );
62+
63+ UserCache cache (cache_size);
64+ prepare_cache (cache, cache_size);
65+
66+ for (auto _ : state) {
67+ state.PauseTiming ();
68+ std::vector<User> users;
69+ for (size_t i = 0 ; i < operations_count; ++i) {
70+ users.push_back (generator::generate_user ());
71+ }
72+ state.ResumeTiming ();
73+
74+ for (size_t i = 0 ; i < operations_count; ++i) {
75+ cache.emplace (users[i]);
76+ }
77+ }
78+
79+ state.SetItemsProcessed (state.iterations () * operations_count);
80+ state.SetComplexityN (cache_size);
81+ }
82+ };
83+
84+ void google_benchmark_init (std::string&& output_filename) {
85+ std::vector<char *> args;
86+ std::string prog_name = " benchmark" ;
87+ args.push_back (prog_name.data ());
88+ std::string out_arg = " --benchmark_out=" + output_filename;
89+ args.push_back (out_arg.data ());
90+ std::string format_arg = " --benchmark_out_format=json" ;
91+ args.push_back (format_arg.data ());
92+ int argc = args.size ();
93+ benchmark::Initialize (&argc, args.data ());
94+ }
95+
96+ void google_benchmark_run () {
97+ benchmark::RunSpecifiedBenchmarks ();
98+ benchmark::ClearRegisteredBenchmarks ();
99+ benchmark::Shutdown ();
100+ }
101+
102+ template <
103+ template <typename , typename , typename > class LRUCacheContainer
104+ >
105+ void google_benchmark () {
106+ using UserCache = LRUCacheContainer<
107+ User,
108+ indexed_by<
109+ ordered_unique<tag<id_tag>, member<User, int , &User::id>>,
110+ ordered_unique<tag<email_tag>, member<User, std::string, &User::email>>,
111+ ordered_non_unique<tag<name_tag>, member<User, std::string, &User::name>>
112+ >,
113+ std::allocator<User>
114+ >;
115+
116+ lru_concept_assert_for_one_tag (UserCache, id_tag, int , User);
117+ lru_concept_assert_for_one_tag (UserCache, email_tag, std::string, User);
118+ lru_concept_assert_for_one_tag (UserCache, name_tag, std::string, User);
119+
120+ for (auto size : CACHE_SIZES) {
121+ benchmark::RegisterBenchmark (
122+ " GetOperations" ,
123+ &LRUCacheBenchmark<LRUCacheContainer>::BM_GetOperations
124+ )->Args ({size, OPERATIONS_NUMBER})->Unit (benchmark::kMicrosecond );
125+ }
126+
127+ for (auto size : CACHE_SIZES) {
128+ benchmark::RegisterBenchmark (
129+ " EmplaceOperations" ,
130+ &LRUCacheBenchmark<LRUCacheContainer>::BM_EmplaceOperations
131+ )->Args ({size, OPERATIONS_NUMBER})->Unit (benchmark::kMicrosecond );
132+ }
133+ }
134+
135+ } // namespace benchmark
0 commit comments