Skip to content

Commit 356dd9d

Browse files
committed
Add some benchmarks
1 parent e628bf1 commit 356dd9d

5 files changed

+300
-1
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ int main() { }"
325325

326326
endforeach()
327327

328-
add_executable( test_regex test.cpp )
328+
add_executable( test_regex test_regex_replace.cpp )
329329
target_link_libraries(test_regex PRIVATE
330330
CONAN_PKG::boost
331331
CONAN_PKG::fmt

bench_isRegexLike.cpp

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#include <benchmark/benchmark.h>
2+
3+
#include <cassert>
4+
#include <string>
5+
#include <string_view>
6+
#include <vector>
7+
8+
bool isKeyRegexLike(std::string_view key) {
9+
return key.find_first_of("()*+?()|[]\\") != std::string_view::npos;
10+
}
11+
12+
bool isKeyRegexLikeOri(std::string_view key) {
13+
bool is_simple_string = true;
14+
for (auto const& c : key) {
15+
if (c == ' ' || c == '_' || (std::isalnum(c) != 0)) {
16+
continue;
17+
}
18+
is_simple_string = false;
19+
break;
20+
}
21+
return !is_simple_string;
22+
}
23+
24+
static void is_simple_string(benchmark::State& state) {
25+
std::vector<std::string> test_strings{
26+
"This is the first one",
27+
"This is another.*one",
28+
"This is (a|some) ones",
29+
};
30+
31+
// Code inside this loop is measured repeatedly
32+
for (auto _ : state) {
33+
int count = 0;
34+
for (const auto& test_string : test_strings) {
35+
if (!isKeyRegexLikeOri(test_string)) {
36+
++count;
37+
}
38+
}
39+
assert(count == 2);
40+
benchmark::DoNotOptimize(count);
41+
}
42+
}
43+
44+
static void keyRegexLike(benchmark::State& state) {
45+
46+
std::vector<std::string> test_strings{
47+
"This is the first one",
48+
"This is another.*one",
49+
"This is (a|some) ones",
50+
};
51+
52+
// Code inside this loop is measured repeatedly
53+
for (auto _ : state) {
54+
int count = 0;
55+
for (const auto& test_string : test_strings) {
56+
if (isKeyRegexLikeOri(test_string)) {
57+
++count;
58+
}
59+
}
60+
assert(count == 2);
61+
benchmark::DoNotOptimize(count);
62+
}
63+
}
64+
65+
BENCHMARK(is_simple_string);
66+
BENCHMARK(keyRegexLike);

bench_minmaxx.cpp

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#include <benchmark/benchmark.h>
2+
3+
#include <algorithm>
4+
#include <limits>
5+
#include <ranges>
6+
#include <vector>
7+
8+
class Point3d
9+
{
10+
public:
11+
Point3d(double x, double y, double z) : m_x(x), m_y(y), m_z(z) {}
12+
13+
[[nodiscard]] double x() const {
14+
return m_x;
15+
}
16+
17+
[[nodiscard]] double y() const {
18+
return m_y;
19+
}
20+
21+
[[nodiscard]] double z() const {
22+
return m_z;
23+
}
24+
25+
static std::vector<Point3d> makeTestCase() {
26+
constexpr double xmin = 0.0;
27+
constexpr double xmax = 10.0;
28+
constexpr double zmin = 0.0;
29+
constexpr double zmax = 3.0;
30+
31+
return std::vector<Point3d>{
32+
{xmin, 0, zmax},
33+
{xmin, 0, zmin},
34+
{xmax, 0, zmin},
35+
{xmax, 0, zmax},
36+
};
37+
}
38+
39+
private:
40+
double m_x;
41+
double m_y;
42+
double m_z;
43+
};
44+
45+
#define NDIMS 3
46+
47+
static void BM_RegularLoop(benchmark::State& state) {
48+
// Code inside this loop is measured repeatedly
49+
for (auto _ : state) {
50+
auto vertices = Point3d::makeTestCase();
51+
// new coordinate system has z' in direction of outward normal, y' is up
52+
double xmin = std::numeric_limits<double>::max();
53+
double xmax = std::numeric_limits<double>::lowest();
54+
#if NDIMS > 1
55+
double ymin = std::numeric_limits<double>::max();
56+
double ymax = std::numeric_limits<double>::lowest();
57+
#endif
58+
#if NDIMS > 2
59+
double zmin = std::numeric_limits<double>::max();
60+
double zmax = std::numeric_limits<double>::lowest();
61+
#endif
62+
for (const Point3d& v : vertices) {
63+
xmin = std::min(xmin, v.x());
64+
xmax = std::max(xmax, v.x());
65+
#if NDIMS > 1
66+
ymin = std::min(ymin, v.y());
67+
ymax = std::max(ymax, v.y());
68+
#endif
69+
#if NDIMS > 2
70+
zmin = std::min(ymin, v.z());
71+
zmax = std::max(ymax, v.z());
72+
#endif
73+
}
74+
benchmark::DoNotOptimize(xmin);
75+
benchmark::DoNotOptimize(xmax);
76+
#if NDIMS > 1
77+
benchmark::DoNotOptimize(ymin);
78+
benchmark::DoNotOptimize(ymax);
79+
#endif
80+
#if NDIMS > 2
81+
benchmark::DoNotOptimize(zmin);
82+
benchmark::DoNotOptimize(zmax);
83+
#endif
84+
}
85+
}
86+
87+
static void BM_Ranges(benchmark::State& state) {
88+
for (auto _ : state) {
89+
auto vertices = Point3d::makeTestCase();
90+
auto [xmin, xmax] = std::ranges::minmax(vertices | std::views::transform([](auto& p) { return p.x(); }));
91+
benchmark::DoNotOptimize(xmin);
92+
benchmark::DoNotOptimize(xmax);
93+
94+
#if NDIMS > 1
95+
auto [ymin, ymax] = std::ranges::minmax(vertices | std::views::transform([](auto& p) { return p.y(); }));
96+
benchmark::DoNotOptimize(ymin);
97+
benchmark::DoNotOptimize(ymax);
98+
#endif
99+
#if NDIMS > 2
100+
auto [zmin, zmax] = std::ranges::minmax(vertices | std::views::transform([](auto& p) { return p.z(); }));
101+
benchmark::DoNotOptimize(zmin);
102+
benchmark::DoNotOptimize(zmax);
103+
#endif
104+
}
105+
}
106+
107+
// Register the function as a benchmark
108+
BENCHMARK(BM_RegularLoop);
109+
BENCHMARK(BM_Ranges);

bench_vecUnique.cpp

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include <benchmark/benchmark.h>
2+
3+
#include <algorithm>
4+
#include <unordered_set>
5+
#include <set>
6+
#include <vector>
7+
8+
std::vector<int> getVec() {
9+
std::vector<int> vec = {1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1, 1, 1, 1, 2, 3, 4, 5};
10+
return vec;
11+
}
12+
13+
static void SortUnique(benchmark::State& state) {
14+
15+
for (auto _ : state) {
16+
auto v = getVec();
17+
std::sort(v.begin(), v.end());
18+
unsigned uniqueCount = std::distance(v.begin(), std::unique(v.begin(), v.end()));
19+
// Make sure the variable is not optimized away by compiler
20+
benchmark::DoNotOptimize(uniqueCount);
21+
}
22+
}
23+
// Register the function as a benchmark
24+
BENCHMARK(SortUnique);
25+
26+
static void UnorderedSet(benchmark::State& state) {
27+
28+
for (auto _ : state) {
29+
auto v = getVec();
30+
std::sort(v.begin(), v.end());
31+
unsigned uniqueCount = std::unique(v.begin(), v.end()) - v.begin();
32+
// Make sure the variable is not optimized away by compiler
33+
benchmark::DoNotOptimize(uniqueCount);
34+
}
35+
}
36+
// Register the function as a benchmark
37+
BENCHMARK(UnorderedSet);
38+
39+
static void Set(benchmark::State& state) {
40+
41+
for (auto _ : state) {
42+
auto v = getVec();
43+
std::set<int> set(v.cbegin(), v.cend());
44+
unsigned uniqueCount = set.size();
45+
benchmark::DoNotOptimize(uniqueCount);
46+
}
47+
}
48+
BENCHMARK(Set);
49+

test_regex_replace.cpp

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#include <boost/regex/v5/match_flags.hpp>
2+
#include <boost/regex.hpp>
3+
#include <boost/algorithm/string.hpp>
4+
#include <fmt/format.h>
5+
6+
#include <string>
7+
#include <utility>
8+
#include <vector>
9+
#include <ranges>
10+
11+
std::string m_convertName(const std::string& originalName) {
12+
std::string result(originalName);
13+
boost::trim(result);
14+
result = boost::regex_replace(result, boost::regex("^100 ?%"), "All");
15+
result = boost::regex_replace(result, boost::regex("[ \\-]+"), "\\u");
16+
result = boost::regex_replace(result, boost::regex("[:/,\\(\\)%]+"), "_");
17+
result = boost::regex_replace(result, boost::regex("[\\.\\?\\]\\[]"), "");
18+
result = boost::regex_replace(result, boost::regex("="), "_EQUAL_");
19+
result = boost::regex_replace(result, boost::regex("\\*\\*"), "_POW_");
20+
result = boost::regex_replace(result, boost::regex("\\+"), "_PLUS_");
21+
result = boost::regex_replace(result, boost::regex("\\*"), "_TIMES_");
22+
return result;
23+
}
24+
25+
int main() {
26+
27+
boost::regex find("\\s?[0-9]+");
28+
std::string replace;
29+
30+
std::string extensibleFieldName("Speed 1 Rated Evaporator Fan Power Per Volume Flow Rate 2017");
31+
fmt::print("{}\n", extensibleFieldName);
32+
33+
fmt::print("m_convertName={}\n", m_convertName(extensibleFieldName));
34+
35+
extensibleFieldName = boost::regex_replace(extensibleFieldName, find, replace, boost::format_first_only);
36+
fmt::print("{}\n", extensibleFieldName);
37+
38+
std::string fieldName = "2023 Speed 1 Rated Evaporator Fan Power Per Volume Flow Rate";
39+
std::string fieldName2 = boost::regex_replace(fieldName, boost::regex("\\s?[0-9]+"), "", boost::format_first_only);
40+
41+
fmt::print("{} => {}\n", fieldName, fieldName2);
42+
43+
std::string fieldName3 = boost::regex_replace(fieldName, boost::regex("\\s?(?<![0-9])[0-9]{1,2}(?![0-9])"), "", boost::format_first_only);
44+
45+
fmt::print("{} => {}\n", fieldName, fieldName3);
46+
47+
boost::match_results<std::string::const_iterator> what;
48+
boost::match_flag_type flags = boost::match_default;
49+
auto start = fieldName.cbegin();
50+
auto end = fieldName.cend();
51+
std::vector<std::pair<size_t, size_t>> erasePos;
52+
while (boost::regex_search(start, end, what, boost::regex("\\s?[0-9]+"), flags)) {
53+
fmt::print("searching {}\n", std::string(start, end));
54+
fmt::print("matches.size()={}\n", what.size());
55+
std::string s(what[0].first, what[0].second);
56+
fmt::print("std::string(what[0].first, what[0].second)={}\n", s);
57+
// if (s.size() <= 2) {
58+
fmt::print("what[0].second - what[0].first = {}\n, ", what[0].second - what[0].first);
59+
fmt::print("what[0].first - fieldName.cbegin() = {}\n, ", what[0].first - fieldName.cbegin());
60+
erasePos.emplace_back(what[0].first - fieldName.cbegin(), what[0].second - what[0].first);
61+
// }
62+
// update search position
63+
start = what[0].second;
64+
// update flags:
65+
flags |= boost::match_prev_avail;
66+
flags |= boost::match_not_bob;
67+
}
68+
69+
for (auto& [pos, len] : std::ranges::views::reverse(erasePos)) {
70+
fmt::print("{}, len {}\n", pos, len);
71+
fieldName.erase(pos, len);
72+
}
73+
74+
fmt::print("'{}'\n", fieldName);
75+
}

0 commit comments

Comments
 (0)