Skip to content

Commit 62ed60e

Browse files
committed
simplify the benchmark
1 parent 62fb615 commit 62ed60e

File tree

2 files changed

+85
-52
lines changed

2 files changed

+85
-52
lines changed

benchmarks/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ include(FetchContent)
33
FetchContent_Declare(
44
counters
55
GIT_REPOSITORY https://github.com/lemire/counters.git
6-
GIT_TAG v2.0.0
6+
GIT_TAG v2.1.0
77
)
88

99
FetchContent_MakeAvailable(counters)

benchmarks/bench_ip.cpp

Lines changed: 84 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,28 @@ void pretty_print(size_t volume, size_t bytes, std::string name,
2626
printf("\n");
2727
}
2828

29+
const char *seek_ip_end(const char *p, const char *pend) {
30+
const char *current = p;
31+
size_t count = 0;
32+
for (; current != pend; ++current) {
33+
if (*current == '.') {
34+
count++;
35+
if (count == 3) {
36+
++current;
37+
break;
38+
}
39+
}
40+
}
41+
while (current != pend) {
42+
if (*current <= '9' && *current >= '0') {
43+
++current;
44+
} else {
45+
break;
46+
}
47+
}
48+
return current;
49+
}
50+
2951
int parse_u8_fastfloat(const char *&p, const char *pend, uint8_t *out) {
3052
if (p == pend)
3153
return 0;
@@ -39,8 +61,9 @@ int parse_u8_fastfloat(const char *&p, const char *pend, uint8_t *out) {
3961

4062
static inline int parse_u8_fromchars(const char *&p, const char *pend,
4163
uint8_t *out) {
42-
if (p == pend)
64+
if (p == pend) {
4365
return 0;
66+
}
4467
auto r = std::from_chars(p, pend, *out);
4568
if (r.ec == std::errc()) {
4669
p = r.ptr;
@@ -50,26 +73,35 @@ static inline int parse_u8_fromchars(const char *&p, const char *pend,
5073
}
5174

5275
template <typename Parser>
53-
static inline int parse_ip_line(const char *&p, const char *pend, uint32_t &sum,
54-
Parser parse_uint8) {
55-
uint8_t o = 0;
56-
for (int i = 0; i < 4; ++i) {
57-
if (!parse_uint8(p, pend, &o))
58-
return 0;
59-
sum += o;
60-
if (i != 3) {
61-
if (p == pend || *p != '.')
62-
return 0;
63-
++p;
64-
}
76+
std::pair<bool, uint32_t> simple_parse_ip_line(const char *p, const char *pend,
77+
Parser parse_uint8) {
78+
uint8_t v1;
79+
if (!parse_uint8(p, pend, &v1)) {
80+
return {false, 0};
81+
}
82+
if (p == pend || *p++ != '.') {
83+
return {false, 0};
84+
}
85+
uint8_t v2;
86+
if (!parse_uint8(p, pend, &v2)) {
87+
return {false, 0};
88+
}
89+
if (p == pend || *p++ != '.') {
90+
return {false, 0};
91+
}
92+
uint8_t v3;
93+
if (!parse_uint8(p, pend, &v3)) {
94+
return {false, 0};
6595
}
66-
// consume optional '\r'
67-
if (p != pend && *p == '\r')
68-
++p;
69-
// expect '\n' or end
70-
if (p != pend && *p == '\n')
71-
++p;
72-
return 1;
96+
if (p == pend || *p++ != '.') {
97+
return {false, 0};
98+
}
99+
uint8_t v4;
100+
if (!parse_uint8(p, pend, &v4)) {
101+
return {false, 0};
102+
}
103+
return {true, (uint32_t(v1) << 24) | (uint32_t(v2) << 16) |
104+
(uint32_t(v3) << 8) | uint32_t(v4)};
73105
}
74106

75107
static std::string make_ip_line(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
@@ -87,19 +119,22 @@ static std::string make_ip_line(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
87119
}
88120

89121
int main() {
90-
constexpr size_t N = 500000;
122+
constexpr size_t N = 15000;
91123
std::mt19937 rng(1234);
92124
std::uniform_int_distribution<int> dist(0, 255);
93125

94126
std::string buf;
95-
buf.reserve(N * 16);
127+
constexpr size_t ip_size = 16;
128+
buf.reserve(N * ip_size);
96129

97130
for (size_t i = 0; i < N; ++i) {
98131
uint8_t a = (uint8_t)dist(rng);
99132
uint8_t b = (uint8_t)dist(rng);
100133
uint8_t c = (uint8_t)dist(rng);
101134
uint8_t d = (uint8_t)dist(rng);
102-
buf += make_ip_line(a, b, c, d);
135+
std::string ip_line = make_ip_line(a, b, c, d);
136+
ip_line.resize(ip_size, ' '); // pad to fixed size
137+
buf.append(ip_line);
103138
}
104139

105140
// sentinel to allow 4-byte loads at end
@@ -108,40 +143,35 @@ int main() {
108143
const size_t bytes = buf.size() - 4; // exclude sentinel from throughput
109144
const size_t volume = N;
110145

111-
// validate correctness
112-
{
113-
const char *start = buf.data();
114-
const char *end = buf.data() + bytes;
115-
const char *p = start;
116-
const char *pend = end;
117-
uint32_t sum = 0;
118-
for (size_t i = 0; i < N; ++i) {
119-
int ok = parse_ip_line(p, pend, sum, parse_u8_fromchars);
120-
if (!ok) {
121-
std::fprintf(stderr, "fromchars parse failed at line %zu\n", i);
122-
std::abort();
123-
}
124-
p = start;
125-
pend = end;
126-
ok = parse_ip_line(p, pend, sum, parse_u8_fastfloat);
127-
if (!ok) {
128-
std::fprintf(stderr, "fastswar parse failed at line %zu\n", i);
129-
std::abort();
130-
}
131-
}
132-
}
146+
volatile uint32_t sink = 0;
133147

134-
uint32_t sink = 0;
148+
pretty_print(volume, bytes, "just_seek_ip_end (no parse)",
149+
counters::bench([&]() {
150+
const char *p = buf.data();
151+
const char *pend = buf.data() + bytes;
152+
uint32_t sum = 0;
153+
int ok = 0;
154+
for (size_t i = 0; i < N; ++i) {
155+
const char *q = seek_ip_end(p, pend);
156+
sum += (uint32_t)(q - p);
157+
p += ip_size;
158+
}
159+
sink += sum;
160+
}));
135161

136162
pretty_print(volume, bytes, "parse_ip_std_fromchars", counters::bench([&]() {
137163
const char *p = buf.data();
138164
const char *pend = buf.data() + bytes;
139165
uint32_t sum = 0;
140166
int ok = 0;
141167
for (size_t i = 0; i < N; ++i) {
142-
ok = parse_ip_line(p, pend, sum, parse_u8_fromchars);
143-
if (!ok)
168+
auto [ok, ip] =
169+
simple_parse_ip_line(p, pend, parse_u8_fromchars);
170+
sum += ip;
171+
if (!ok) {
144172
std::abort();
173+
}
174+
p += ip_size;
145175
}
146176
sink += sum;
147177
}));
@@ -152,13 +182,16 @@ int main() {
152182
uint32_t sum = 0;
153183
int ok = 0;
154184
for (size_t i = 0; i < N; ++i) {
155-
ok = parse_ip_line(p, pend, sum, parse_u8_fastfloat);
156-
if (!ok)
185+
auto [ok, ip] =
186+
simple_parse_ip_line(p, pend, parse_u8_fastfloat);
187+
sum += ip;
188+
if (!ok) {
157189
std::abort();
190+
}
191+
p += ip_size;
158192
}
159193
sink += sum;
160194
}));
161195

162-
std::printf("sink=%u\n", sink);
163196
return EXIT_SUCCESS;
164197
}

0 commit comments

Comments
 (0)