-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathregex_probe.cpp
More file actions
132 lines (116 loc) · 4.38 KB
/
Copy pathregex_probe.cpp
File metadata and controls
132 lines (116 loc) · 4.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Sonde : ou part le temps dans le test regex cote C++ ?
#define NOMINMAX
#include <windows.h>
#include <chrono>
#include <cstdint>
#include <cstdio>
#include <regex>
#include <string>
#include <vector>
struct Rng {
uint64_t s;
explicit Rng(uint64_t seed) : s(seed ? seed : 1) {}
uint64_t next_u64() {
s ^= s >> 12; s ^= s << 25; s ^= s >> 27;
return s * 2685821657736338717ULL;
}
};
static const char* LVL[5] = {"INFO", "WARN", "ERROR", "DEBUG", "TRACE"};
static std::string build_log_text(int nlines) {
Rng rng(0xD1B54A32D192ED03ULL);
std::string out;
out.reserve((size_t)nlines * 84);
char line[256];
static const int STATUS[6] = {200, 201, 301, 400, 404, 500};
for (int k = 0; k < nlines; ++k) {
uint64_t r1 = rng.next_u64(), r2 = rng.next_u64();
int len = snprintf(line, sizeof(line),
"%04d-%02d-%02dT%02d:%02d:%02d [%-5s] svc-%03d req=%08x latency_ms=%d status=%d",
2020 + (int)(r1 % 6), 1 + (int)((r1 >> 8) % 12), 1 + (int)((r1 >> 16) % 28),
(int)((r1 >> 24) % 24), (int)((r1 >> 32) % 60), (int)((r1 >> 40) % 60),
LVL[(int)((r2 >> 3) % 5)], (int)((r2 >> 11) % 1000),
(unsigned)(r2 & 0xFFFFFFFFULL), (int)((r2 >> 21) % 5000),
STATUS[(int)((r2 >> 33) % 6)]);
if (k) out.push_back('\n');
out.append(line, (size_t)len);
}
return out;
}
typedef std::chrono::steady_clock clk;
template <class F>
static void bench(const char* name, F fn) {
long matches = fn(); // rodage
auto t0 = clk::now();
int passes = 0;
double el = 0;
do {
matches = fn();
++passes;
el = std::chrono::duration<double>(clk::now() - t0).count();
} while (el < 1.0);
printf(" %-46s %9.2f ms/passe %6ld matches\n", name, el / passes * 1000.0, matches);
}
static bool shape_ok(const char* p) {
static const char mask[] = "dddd-dd-ddTdd:dd:dd";
for (int k = 0; k < 19; ++k) {
if (mask[k] == 'd') { if (p[k] < '0' || p[k] > '9') return false; }
else if (p[k] != mask[k]) return false;
}
return true;
}
int main() {
std::string text = build_log_text(4000);
printf("\n texte : %.1f Ko, %d lignes\n\n", text.size() / 1024.0, 4000);
std::regex rx_cap(R"((\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}))",
std::regex::ECMAScript | std::regex::optimize);
std::regex rx_nocap(R"(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})",
std::regex::ECMAScript | std::regex::optimize);
bench("1. sregex_iterator + 6 captures (le bench)", [&]() -> long {
long n = 0;
for (auto it = std::sregex_iterator(text.begin(), text.end(), rx_cap);
it != std::sregex_iterator(); ++it) ++n;
return n;
});
bench("2. regex_search, smatch reutilise, 6 captures", [&]() -> long {
long n = 0;
std::smatch m;
auto b = text.cbegin();
while (std::regex_search(b, text.cend(), m, rx_cap)) { ++n; b = m[0].second; }
return n;
});
bench("3. regex_search, cmatch (const char*), 6 captures", [&]() -> long {
long n = 0;
std::cmatch m;
const char* b = text.c_str();
const char* e = b + text.size();
while (std::regex_search(b, e, m, rx_cap)) { ++n; b = m[0].second; }
return n;
});
bench("4. regex_search, cmatch, SANS capture", [&]() -> long {
long n = 0;
std::cmatch m;
const char* b = text.c_str();
const char* e = b + text.size();
while (std::regex_search(b, e, m, rx_nocap)) { ++n; b = m[0].second; }
return n;
});
std::regex rx_noquant(R"((\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d))",
std::regex::ECMAScript | std::regex::optimize);
bench("5. MEME regex sans quantificateur {n}", [&]() -> long {
long n = 0;
for (auto it = std::sregex_iterator(text.begin(), text.end(), rx_noquant);
it != std::sregex_iterator(); ++it) ++n;
return n;
});
bench("6. scanner ecrit a la main (pas de regex)", [&]() -> long {
long n = 0;
const char* p = text.c_str();
size_t lim = text.size() >= 19 ? text.size() - 19 : 0;
for (size_t i = 0; i < lim; ++i) {
if (p[i] >= '0' && p[i] <= '9' && shape_ok(p + i)) { ++n; i += 18; }
}
return n;
});
printf("\n");
return 0;
}