Introduce non-throwing try* methods for IPAddress{,V4,V6}.
[folly.git] / folly / test / IPAddressBenchmark.cpp
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
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
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <folly/Format.h>
18 #include <folly/IPAddress.h>
19
20 #include <glog/logging.h>
21
22 #include <folly/Benchmark.h>
23
24 using namespace folly;
25 using std::string;
26
27 BENCHMARK(ipv4_to_string_inet_ntop, iters) {
28   folly::IPAddressV4 ipv4Addr("127.0.0.1");
29   in_addr ip = ipv4Addr.toAddr();
30   char outputString[INET_ADDRSTRLEN] = {0};
31
32   while (iters--) {
33     const char* val =
34         inet_ntop(AF_INET, &ip, outputString, sizeof(outputString));
35     folly::doNotOptimizeAway(val);
36   }
37 }
38
39 BENCHMARK_RELATIVE(ipv4_to_fully_qualified, iters) {
40   IPAddressV4 ip("127.0.0.1");
41   while (iters--) {
42     string outputString = ip.toFullyQualified();
43     folly::doNotOptimizeAway(outputString);
44     folly::doNotOptimizeAway(outputString.data());
45   }
46 }
47
48 BENCHMARK_DRAW_LINE()
49
50 BENCHMARK(ipv4_to_fully_qualified_port, iters) {
51   IPAddressV4 ip("255.255.255.255");
52   while (iters--) {
53     string outputString = folly::sformat("{}:{}", ip.toFullyQualified(), 65535);
54     folly::doNotOptimizeAway(outputString);
55     folly::doNotOptimizeAway(outputString.data());
56   }
57 }
58
59 BENCHMARK_RELATIVE(ipv4_append_to_fully_qualified_port, iters) {
60   IPAddressV4 ip("255.255.255.255");
61   while (iters--) {
62     string outputString;
63     outputString.reserve(IPAddressV4::kMaxToFullyQualifiedSize + 1 + 5);
64     ip.toFullyQualifiedAppend(outputString);
65     outputString += ':';
66     folly::toAppend(65535, &outputString);
67     folly::doNotOptimizeAway(outputString);
68     folly::doNotOptimizeAway(outputString.data());
69   }
70 }
71
72 BENCHMARK_DRAW_LINE()
73
74 BENCHMARK(ipv6_to_string_inet_ntop, iters) {
75   IPAddressV6 ipv6Addr("F1E0:0ACE:FB94:7ADF:22E8:6DE6:9672:3725");
76   in6_addr ip = ipv6Addr.toAddr();
77   char outputString[INET6_ADDRSTRLEN] = {0};
78
79   while (iters--) {
80     const char* val =
81         inet_ntop(AF_INET6, &ip, outputString, sizeof(outputString));
82     folly::doNotOptimizeAway(val);
83   }
84 }
85
86 BENCHMARK_RELATIVE(ipv6_to_fully_qualified, iters) {
87   IPAddressV6 ip("F1E0:0ACE:FB94:7ADF:22E8:6DE6:9672:3725");
88   while (iters--) {
89     string outputString = ip.toFullyQualified();
90     folly::doNotOptimizeAway(outputString);
91     folly::doNotOptimizeAway(outputString.data());
92   }
93 }
94
95 BENCHMARK_DRAW_LINE()
96
97 BENCHMARK(ipv6_to_fully_qualified_port, iters) {
98   IPAddressV6 ip("F1E0:0ACE:FB94:7ADF:22E8:6DE6:9672:3725");
99   while (iters--) {
100     string outputString = folly::sformat("{}:{}", ip.toFullyQualified(), 65535);
101     folly::doNotOptimizeAway(outputString);
102     folly::doNotOptimizeAway(outputString.data());
103   }
104 }
105
106 BENCHMARK_RELATIVE(ipv6_append_to_fully_qualified_port, iters) {
107   IPAddressV6 ip("F1E0:0ACE:FB94:7ADF:22E8:6DE6:9672:3725");
108   while (iters--) {
109     string outputString;
110     outputString.reserve(folly::IPAddressV6::kToFullyQualifiedSize + 1 + 5);
111     ip.toFullyQualifiedAppend(outputString);
112     outputString += ':';
113     folly::toAppend(65535, &outputString);
114     folly::doNotOptimizeAway(outputString);
115     folly::doNotOptimizeAway(outputString.data());
116   }
117 }
118
119 BENCHMARK_DRAW_LINE()
120
121 BENCHMARK(ipv6_ctor_valid, iters) {
122   while (iters--) {
123     try {
124       IPAddressV6 ip("2803:6082:18e0:2c49:1a23:9ee0:5c87:9800");
125       doNotOptimizeAway(ip);
126     } catch (const IPAddressFormatException& ex) {
127       doNotOptimizeAway(ex);
128     }
129   }
130 }
131
132 BENCHMARK_RELATIVE(ipv6_ctor_invalid, iters) {
133   while (iters--) {
134     try {
135       IPAddressV6 ip("2803:6082:18e0:2c49:1a23:9ee0:5c87:980r");
136       doNotOptimizeAway(ip);
137     } catch (const IPAddressFormatException& ex) {
138       doNotOptimizeAway(ex);
139     }
140   }
141 }
142
143 BENCHMARK_DRAW_LINE()
144
145 BENCHMARK(ipv6_try_from_string_valid, iters) {
146   while (iters--) {
147     auto maybeIp =
148         IPAddressV6::tryFromString("2803:6082:18e0:2c49:1a23:9ee0:5c87:9800");
149     CHECK(maybeIp.hasValue());
150     doNotOptimizeAway(maybeIp);
151     doNotOptimizeAway(maybeIp.value());
152   }
153 }
154
155 BENCHMARK_RELATIVE(ipv6_try_from_string_invalid, iters) {
156   while (iters--) {
157     auto maybeIp =
158         IPAddressV6::tryFromString("2803:6082:18e0:2c49:1a23:9ee0:5c87:980r");
159     CHECK(maybeIp.hasError());
160     doNotOptimizeAway(maybeIp);
161     doNotOptimizeAway(maybeIp.error());
162   }
163 }
164
165 // Benchmark results on Intel Xeon CPU E5-2660 @ 2.20GHz
166 // ============================================================================
167 // folly/test/IPAddressBenchmark.cpp               relative  time/iter  iters/s
168 // ============================================================================
169 // ipv4_to_string_inet_ntop                                   227.13ns    4.40M
170 // ipv4_to_fully_qualified                         1418.95%    16.01ns   62.47M
171 // ----------------------------------------------------------------------------
172 // ipv4_to_fully_qualified_port                                77.51ns   12.90M
173 // ipv4_append_to_fully_qualified_port              133.72%    57.96ns   17.25M
174 // ----------------------------------------------------------------------------
175 // ipv6_to_string_inet_ntop                                   750.53ns    1.33M
176 // ipv6_to_fully_qualified                          608.68%   123.30ns    8.11M
177 // ----------------------------------------------------------------------------
178 // ipv6_to_fully_qualified_port                               150.76ns    6.63M
179 // ipv6_append_to_fully_qualified_port              178.73%    84.35ns   11.86M
180 // ----------------------------------------------------------------------------
181 // ipv6_ctor_valid                                            379.97ns    2.63M
182 // ipv6_ctor_invalid                                 10.38%     3.66us  273.22K
183 // ----------------------------------------------------------------------------
184 // ipv6_try_from_string_valid                                 375.34ns    2.66M
185 // ipv6_try_from_string_invalid                     111.93%   335.34ns    2.98M
186 // ============================================================================
187
188 int main(int argc, char* argv[]) {
189   gflags::ParseCommandLineFlags(&argc, &argv, true);
190   runBenchmarks();
191   return 0;
192 }