proxygen
PerfectIndexMapBenchmark.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree. An additional grant
7  * of patent rights can be found in the PATENTS file in the same directory.
8  *
9  */
10 #include <algorithm>
11 #include <folly/Benchmark.h>
14 #include <unordered_map>
15 
16 using namespace folly;
17 using namespace proxygen;
18 
19 // buck build @mode/opt proxygen/lib/utils/test:perfect_index_map_benchmark
20 // ./buck-out/gen/proxygen/lib/utils/test/perfect_index_map_benchmark -bm_min_iters 1000
21 // ============================================================================
22 // proxygen/lib/utils/test/PerfectIndexMapBenchmark.cpprelative time/iter iters/s
23 // ============================================================================
24 // proxygen/lib/utils/test/PerfectIndexMapBenchmark.cpprelative time/iter iters/s
25 // ============================================================================
26 // UnorderedMapUniqueInserts 8.80us 113.62K
27 // UnorderedMapUniqueGets 9.95us 100.49K
28 // PerfectIndexMapUniqueInsertsCode 3.12us 320.90K
29 // PerfectIndexMapUniqueInsertsHashCodeString 7.35us 136.09K
30 // PerfectIndexMapUniqueInsertsHashOtherString 37.07us 26.98K
31 // PerfectIndexMapUniqueGetsCode 4.71us 212.23K
32 // PerfectIndexMapUniqueGetsCodeString 8.97us 111.49K
33 // PerfectIndexMapUniqueGetsOtherString 36.23us 27.60K
34 // ============================================================================
35 
36 namespace {
37 
38 std::vector<HTTPHeaderCode> getTestHeaderCodes() {
39  std::vector<HTTPHeaderCode> testHeaderCodes;
41  j < HTTPCommonHeaders::num_header_codes; ++j) {
42  testHeaderCodes.push_back(static_cast<HTTPHeaderCode>(j));
43  }
44  return testHeaderCodes;
45 }
46 
47 std::vector<const std::string *> getTestHeaderCodeStrings() {
48  std::vector<const std::string *> testHeadersCodeStrings;
50  j < HTTPCommonHeaders::num_header_codes; ++j) {
51  testHeadersCodeStrings.push_back(
52  HTTPCommonHeaders::getPointerToHeaderName(
53  static_cast<HTTPHeaderCode>(j)));
54  }
55  return testHeadersCodeStrings;
56 }
57 
58 std::vector<const std::string *> getTestHeaderOtherStrings() {
59  std::vector<const std::string *> testHeadersOtherStrings;
61  j < HTTPCommonHeaders::num_header_codes; ++j) {
62  testHeadersOtherStrings.push_back(
63  new std::string(
64  *HTTPCommonHeaders::getPointerToHeaderName(
65  static_cast<HTTPHeaderCode>(j))
66  + "0"));
67  }
68  return testHeadersOtherStrings;
69 }
70 
71 static const std::vector<HTTPHeaderCode> testHeaderCodes = getTestHeaderCodes();
72 
73 static const std::vector<const std::string *> testHeadersCodeStrings =
74  getTestHeaderCodeStrings();
75 
76 static const std::vector<const std::string *> testHeadersOtherStrings =
77  getTestHeaderOtherStrings();
78 
79 typedef PerfectIndexMap<
83  HTTPCommonHeaders::hash,
84  false,
85  false>
86  DefaultPerfectIndexMap;
87 
88 }
89 
91  std::unordered_map<std::string,std::string>& testMap,
92  const std::vector<const std::string *>& keysAndValues, int iters) {
93  for (int i = 0; i < iters; ++i) {
94  for (auto const& keyAndValue: keysAndValues) {
95  // Modeled after old impl of varstore
96  testMap[*keyAndValue] = *keyAndValue;
97  }
98  }
99 }
100 
102  DefaultPerfectIndexMap &map, const std::vector<HTTPHeaderCode>& keys,
103  const std::vector<const std::string *>& values, int iters) {
104  for (int i = 0; i < iters; ++i) {
105  for (unsigned long j = 0; j < keys.size(); ++j) {
106  map.set(keys[j], *values[j]);
107  }
108  }
109 }
110 
112  DefaultPerfectIndexMap &map,
113  const std::vector<const std::string *>& keysAndValues, int iters) {
114  for (int i = 0; i < iters; ++i) {
115  for (auto const& keyAndValue: keysAndValues) {
116  map.set(*keyAndValue, *keyAndValue);
117  }
118  }
119 }
120 
122  std::unordered_map<std::string,std::string>& testMap,
123  const std::vector<const std::string *>& keys, int iters) {
124  for (int i = 0; i < iters; ++i) {
125  for (auto const& key: keys) {
126  // Modeled after old impl of varstore
127  auto it = testMap.find(*key);
129  it == testMap.end() ?
131  CHECK(result != folly::none);
132  }
133  }
134 }
135 
137  DefaultPerfectIndexMap &map, const std::vector<HTTPHeaderCode>& keys,
138  int iters) {
139  for (int i = 0; i < iters; ++i) {
140  for (auto const& key: keys) {
141  CHECK(map.getSingleOrNone(key) != folly::none);
142  }
143  }
144 }
145 
147  DefaultPerfectIndexMap &map, const std::vector<const std::string *>& keys,
148  int iters) {
149  for (int i = 0; i < iters; ++i) {
150  for (auto const& key: keys) {
151  CHECK(map.getSingleOrNone(*key) != folly::none);
152  }
153  }
154 }
155 
156 std::unordered_map<std::string, std::string> bUnorderedMapUniqueInsertsMap;
157 BENCHMARK(UnorderedMapUniqueInserts, iters) {
159  bUnorderedMapUniqueInsertsMap, testHeadersCodeStrings, iters);
160 }
161 
162 std::unordered_map<std::string, std::string>
164  std::unordered_map<std::string, std::string> testMap;
165  UnorderedMapInsertBench(testMap, testHeadersCodeStrings, 1);
166  return testMap;
167 }
168 std::unordered_map<std::string, std::string> bUnorderedMapUniqueGetsMap =
170 BENCHMARK(UnorderedMapUniqueGets, iters) {
172  bUnorderedMapUniqueGetsMap, testHeadersCodeStrings, iters);
173 }
174 
176 BENCHMARK(PerfectIndexMapUniqueInsertsCode, iters) {
178  bPerfectIndexMapUniqueInsertsCodeMap, testHeaderCodes,
179  testHeadersCodeStrings, iters);
180 }
181 
182 DefaultPerfectIndexMap
184 BENCHMARK(PerfectIndexMapUniqueInsertsHashCodeString, iters) {
187  iters);
188 }
189 
190 DefaultPerfectIndexMap
192 BENCHMARK(PerfectIndexMapUniqueInsertsHashOtherString, iters) {
195  testHeadersOtherStrings, iters);
196 }
197 
199  DefaultPerfectIndexMap testMap;
201  testMap, testHeaderCodes, testHeadersCodeStrings, 1);
202  return testMap;
203 }
204 DefaultPerfectIndexMap bPerfectIndexMapUniqueGetsCodeMap =
206 BENCHMARK(PerfectIndexMapUniqueGetsCode, iters) {
208  bPerfectIndexMapUniqueGetsCodeMap, testHeaderCodes, iters);
209 }
210 
213 BENCHMARK(PerfectIndexMapUniqueGetsCodeString, iters) {
215  bPerfectIndexMapUniqueGetsCodeStringMap, testHeadersCodeStrings, iters);
216 }
217 
219  DefaultPerfectIndexMap testMap;
220  PerfectIndexMapInsertHashBench(testMap, testHeadersOtherStrings, 1);
221  return testMap;
222 }
225 BENCHMARK(PerfectIndexMapUniqueGetsOtherString, iters) {
227  bPerfectIndexMapUniqueGetsOtherStringMap, testHeadersOtherStrings, iters);
228 }
229 
230 int main(int argc, char** argv) {
231  gflags::ParseCommandLineFlags(&argc, &argv, true);
233 
234  // Not explicitly required but lets free memory we specifically allocated.
235  for (auto * testHeaderOtherString: testHeadersOtherStrings) {
236  delete testHeaderOtherString;
237  }
238 
239  return 0;
240 }
void PerfectIndexMapInsertHashBench(DefaultPerfectIndexMap &map, const std::vector< const std::string * > &keysAndValues, int iters)
DefaultPerfectIndexMap bPerfectIndexMapUniqueGetsCodeStringMap
std::unordered_map< std::string, std::string > getBenchUnorderedMapUniqueGetsTestMap()
DefaultPerfectIndexMap bPerfectIndexMapUniqueGetsOtherStringMap
DefaultPerfectIndexMap bPerfectIndexMapUniqueInsertsHashOtherStringTestMap
DefaultPerfectIndexMap bPerfectIndexMapUniqueInsertsCodeMap
void testMap()
void UnorderedMapGetBench(std::unordered_map< std::string, std::string > &testMap, const std::vector< const std::string * > &keys, int iters)
DefaultPerfectIndexMap getBenchPerfectIndexMapUniqueGetsOtherStringTestMap()
DefaultPerfectIndexMap getBenchPerfectIndexMapUniqueGetsCodeTestMap()
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
void runBenchmarks()
Definition: Benchmark.cpp:456
int main(int argc, char **argv)
std::unordered_map< std::string, std::string > bUnorderedMapUniqueGetsMap
char ** argv
void PerfectIndexMapInsertCodeBench(DefaultPerfectIndexMap &map, const std::vector< HTTPHeaderCode > &keys, const std::vector< const std::string * > &values, int iters)
void PerfectIndexMapGetCodeBench(DefaultPerfectIndexMap &map, const std::vector< HTTPHeaderCode > &keys, int iters)
void PerfectIndexMapGetStringBench(DefaultPerfectIndexMap &map, const std::vector< const std::string * > &keys, int iters)
Definition: Traits.h:594
DefaultPerfectIndexMap bPerfectIndexMapUniqueGetsCodeMap
BENCHMARK(fbFollyGlobalBenchmarkBaseline)
Definition: Benchmark.cpp:84
const char * string
Definition: Conv.cpp:212
DefaultPerfectIndexMap bPerfectIndexMapUniqueInsertsHashCodeStringTestMap
const uint8_t HTTPHeaderCodeCommonOffset
std::unordered_map< std::string, std::string > bUnorderedMapUniqueInsertsMap
constexpr None none
Definition: Optional.h:87
std::vector< int > values(1'000)
void UnorderedMapInsertBench(std::unordered_map< std::string, std::string > &testMap, const std::vector< const std::string * > &keysAndValues, int iters)