2 * Copyright 2017 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 // Copyright 2013-present Facebook. All Rights Reserved.
18 #include <folly/Benchmark.h>
19 #include <folly/Conv.h>
20 #include <folly/Range.h>
25 #include <unordered_map>
26 #include <unordered_set>
28 #include <folly/experimental/StringKeyedMap.h>
29 #include <folly/experimental/StringKeyedSet.h>
30 #include <folly/experimental/StringKeyedUnorderedMap.h>
31 #include <folly/experimental/StringKeyedUnorderedSet.h>
33 using folly::StringKeyedMap;
34 using folly::StringKeyedSet;
35 using folly::StringKeyedUnorderedMap;
36 using folly::StringKeyedUnorderedSet;
37 using folly::StringPiece;
42 using std::unordered_map;
43 using std::unordered_set;
44 using namespace std::string_literals;
46 static map<string, int> m;
47 static StringKeyedMap<int> skm;
49 static StringKeyedSet sks;
50 static unordered_map<string, int> um;
51 static StringKeyedUnorderedMap<int> skum;
52 static unordered_set<string> us;
53 static StringKeyedUnorderedSet skus;
54 static const std::string lookup = "1234567890abcdefghijklmnopqrstuvwxyz"s;
55 static const folly::StringPiece lookupPiece{
56 "1234567890abcdefghijklmnopqrstuvwxyz"};
58 #if !defined(FOLLY_HAVE_COMPARE_EQUIVALENT) && _LIBCPP_VERSION >= 3400
59 #define FOLLY_HAVE_COMPARE_EQUIVALENT 1
62 #if !defined(FOLLY_HAVE_COMPARE_EQUIVALENT) && __GNUC__ >= 5
63 #define FOLLY_HAVE_COMPARE_EQUIVALENT 1
66 #if FOLLY_HAVE_COMPARE_EQUIVALENT
67 static map<string, int, std::less<void>> m_equiv;
68 static set<string, std::less<void>> s_equiv;
71 static void initBenchmarks() {
72 for (int i = 0; i < 1000; ++i) {
73 auto iStr = to<string>(i);
77 m.insert(make_pair(lookup, 0));
80 skm = decltype(skm){m.begin(), m.end()};
81 um = decltype(um){m.begin(), m.end()};
82 skum = decltype(skum){m.begin(), m.end()};
84 sks = decltype(sks){s.begin(), s.end()};
85 us = decltype(us){s.begin(), s.end()};
86 skus = decltype(skus){s.begin(), s.end()};
87 #if FOLLY_HAVE_COMPARE_EQUIVALENT
88 m_equiv = decltype(m_equiv){m.begin(), m.end()};
89 s_equiv = decltype(s_equiv){s.begin(), s.end()};
93 BENCHMARK(std_map_benchmark_find_native) {
94 folly::doNotOptimizeAway(m.find(lookup)->second);
97 BENCHMARK_RELATIVE(std_map_benchmark_find_cross) {
98 folly::doNotOptimizeAway(m.find(lookupPiece.str())->second);
101 #if FOLLY_HAVE_COMPARE_EQUIVALENT
102 BENCHMARK_RELATIVE(std_map_benchmark_find_equiv) {
103 folly::doNotOptimizeAway(m_equiv.find(lookupPiece)->second);
107 BENCHMARK_RELATIVE(sk_map_benchmark_find_native) {
108 folly::doNotOptimizeAway(skm.find(lookupPiece)->second);
111 BENCHMARK_RELATIVE(sk_map_benchmark_find_cross) {
112 folly::doNotOptimizeAway(skm.find(lookup)->second);
115 BENCHMARK(std_map_benchmark_erase_emplace_native) {
117 m.emplace(lookup, 123);
120 BENCHMARK_RELATIVE(std_map_benchmark_erase_emplace_cross) {
121 m.erase(lookupPiece.str());
122 m.emplace(lookupPiece.str(), 123);
125 BENCHMARK_RELATIVE(sk_map_benchmark_erase_emplace_native) {
126 skm.erase(lookupPiece);
127 skm.emplace(lookupPiece, 123);
130 BENCHMARK_RELATIVE(sk_map_benchmark_erase_emplace_cross) {
132 skm.emplace(lookup, 123);
135 BENCHMARK(std_unordered_map_benchmark_find_native) {
136 folly::doNotOptimizeAway(um.find(lookup)->second);
139 BENCHMARK_RELATIVE(std_unordered_map_benchmark_find_cross) {
140 folly::doNotOptimizeAway(um.find(lookupPiece.str())->second);
143 BENCHMARK_RELATIVE(sk_unordered_map_benchmark_find_native) {
144 folly::doNotOptimizeAway(skum.find(lookupPiece)->second);
147 BENCHMARK_RELATIVE(sk_unordered_map_benchmark_find_cross) {
148 folly::doNotOptimizeAway(skum.find(lookup)->second);
151 BENCHMARK(std_unordered_map_benchmark_erase_emplace_native) {
153 um.emplace(lookup, 123);
156 BENCHMARK_RELATIVE(std_unordered_map_benchmark_erase_emplace_cross) {
157 um.erase(lookupPiece.str());
158 um.emplace(lookupPiece.str(), 123);
161 BENCHMARK_RELATIVE(sk_unordered_map_benchmark_erase_emplace_native) {
162 skum.erase(lookupPiece);
163 skum.emplace(lookupPiece, 123);
166 BENCHMARK_RELATIVE(sk_unordered_map_benchmark_erase_emplace_cross) {
168 skum.emplace(lookup, 123);
171 BENCHMARK_DRAW_LINE();
173 BENCHMARK(std_set_benchmark_find_native) {
174 folly::doNotOptimizeAway(s.find(lookup));
177 BENCHMARK_RELATIVE(std_set_benchmark_find_cross) {
178 folly::doNotOptimizeAway(s.find(lookupPiece.str()));
181 #if FOLLY_HAVE_COMPARE_EQUIVALENT
182 BENCHMARK_RELATIVE(std_set_benchmark_find_equiv) {
183 folly::doNotOptimizeAway(s_equiv.find(lookupPiece));
187 BENCHMARK_RELATIVE(sk_set_benchmark_find_native) {
188 folly::doNotOptimizeAway(sks.find(lookupPiece));
191 BENCHMARK_RELATIVE(sk_set_benchmark_find_cross) {
192 folly::doNotOptimizeAway(sks.find(lookup));
195 BENCHMARK(std_set_benchmark_erase_emplace_native) {
200 BENCHMARK_RELATIVE(std_set_benchmark_erase_emplace_cross) {
201 s.erase(lookupPiece.str());
202 s.emplace(lookupPiece.str());
205 BENCHMARK_RELATIVE(sk_set_benchmark_erase_emplace_native) {
206 sks.erase(lookupPiece);
207 sks.emplace(lookupPiece);
210 BENCHMARK_RELATIVE(sk_set_benchmark_erase_emplace_cross) {
215 BENCHMARK(std_unordered_set_benchmark_find_native) {
216 folly::doNotOptimizeAway(us.find(lookup));
219 BENCHMARK(std_unordered_set_benchmark_find_cross) {
220 folly::doNotOptimizeAway(us.find(lookupPiece.str()));
223 BENCHMARK_RELATIVE(sk_unordered_set_benchmark_find_native) {
224 folly::doNotOptimizeAway(skus.find(lookupPiece));
227 BENCHMARK_RELATIVE(sk_unordered_set_benchmark_find_cross) {
228 folly::doNotOptimizeAway(skus.find(lookup));
231 BENCHMARK(std_unordered_set_benchmark_erase_emplace_native) {
236 BENCHMARK_RELATIVE(std_unordered_set_benchmark_erase_emplace_cross) {
237 us.erase(lookupPiece.str());
238 us.emplace(lookupPiece.str());
241 BENCHMARK_RELATIVE(sk_unordered_set_benchmark_erase_emplace_native) {
242 skus.erase(lookupPiece);
243 skus.emplace(lookupPiece);
246 BENCHMARK_RELATIVE(sk_unordered_set_benchmark_erase_emplace_cross) {
248 skus.emplace(lookup);
251 int main(int argc, char** argv) {
252 gflags::ParseCommandLineFlags(&argc, &argv, true);
254 folly::runBenchmarks();