Skip to content

Instantly share code, notes, and snippets.

@Harold2017
Forked from qis/regex.cpp
Created June 6, 2022 10:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Harold2017/1320942fdfbd5ee88347c1ac6dbc49b8 to your computer and use it in GitHub Desktop.
Save Harold2017/1320942fdfbd5ee88347c1ac6dbc49b8 to your computer and use it in GitHub Desktop.
// ------------------------------------------------------------------------
// Benchmark LGCG Time LTO Time Iterations LTCG Build LTO Build
// ------------------------------------------------------------------------
// regex_boost 317 ns 69.1 ns 2133333 00:02.720 00:08.70
// regex_ctre 248 ns 4.79 ns 2800000 05:08.755 00:04.78
// regex_hyperscan 96.7 ns n/a 7466667 00:52.487 n/a
// regex_re2 186 ns 3.97 ns 4072727 00:03.353 00:05.94
// regex_spirit 44.3 ns 0.644 ns 15448276 00:03.487 00:05.25
// regex_std 2371 ns 67.2 ns 280000 00:02.442 00:05.54
// regex_xpressive 552 ns 273 ns 1000000 00:05.369 00:11.52
#include <benchmark/benchmark.h>
#include <string>
#include <fstream>
#define PATTERN "[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(\\.\\d*)?"
inline std::string g_s = []() {
std::string s;
if (auto is = std::ifstream{ "C:\\Workspace\\pattern.txt", std::ios::binary }) {
std::getline(is, s);
}
return s;
}();
#include <boost/regex.hpp>
static void regex_boost(benchmark::State& state) {
constexpr auto flags = boost::regex_constants::nosubs | boost::regex_constants::optimize;
boost::regex re(PATTERN, flags);
for (auto _ : state) {
const auto result = boost::regex_match(g_s, re);
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(regex_boost);
#include <ctre.hpp>
static constexpr auto ctre_pattern = ctll::fixed_string{ PATTERN };
static void regex_ctre(benchmark::State& state) {
for (auto _ : state) {
const auto result = ctre::match<ctre_pattern>(g_s);
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(regex_ctre);
#include <hs/hs.h>
static void regex_hyperscan(benchmark::State& state) {
hs_database_t* database = nullptr;
hs_compile_error_t* compile_err = nullptr;
if (hs_compile(PATTERN, HS_FLAG_DOTALL, HS_MODE_BLOCK, NULL, &database, &compile_err) != HS_SUCCESS) {
hs_free_compile_error(compile_err);
throw std::runtime_error("could not compile pattern");
}
hs_scratch_t* scratch = NULL;
if (hs_alloc_scratch(database, &scratch) != HS_SUCCESS) {
hs_free_database(database);
throw std::runtime_error("could not allocate scratch space");
}
const auto data = g_s.data();
const auto size = g_s.size();
const auto e = [](unsigned int id, unsigned long long from, unsigned long long to, unsigned int flags, void* ctx) noexcept -> int {
return 0;
};
for (auto _ : state) {
const auto result = hs_scan(database, data, size, 0, scratch, e, nullptr);
benchmark::DoNotOptimize(result);
}
hs_free_scratch(scratch);
hs_free_database(database);
}
BENCHMARK(regex_hyperscan);
#include <re2/re2.h>
static void regex_re2(benchmark::State& state) {
re2::RE2::Options options{ re2::RE2::Quiet };
options.set_never_capture(true);
re2::RE2 re{ PATTERN, options };
for (auto _ : state) {
const auto result = RE2::FullMatch(g_s, re);
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(regex_re2);
#pragma warning(disable : 4828)
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
x3::rule<struct date> const date = "date";
auto const date_def = x3::repeat(4)[x3::digit] >> "-" >> x3::repeat(2)[x3::digit] >>
"-" >> x3::repeat(2)[x3::digit] >> x3::space >> x3::repeat(2)[x3::digit] >> ":" >> x3::repeat(2)[x3::digit] >>
":" >> x3::repeat(2)[x3::digit] >> -("." >> +x3::digit);
BOOST_SPIRIT_DEFINE(date);
static void regex_spirit(benchmark::State& state) {
const auto beg = g_s.begin();
const auto end = g_s.end();
for (auto _ : state) {
const auto result = x3::parse(beg, end, date);
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(regex_spirit);
#include <regex>
static void regex_std(benchmark::State& state) {
constexpr auto flags = std::regex::nosubs | std::regex::optimize;
std::regex re{ PATTERN, flags };
for (auto _ : state) {
const auto result = std::regex_match(g_s, re);
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(regex_std);
#pragma warning(disable : 4828)
#include <boost/xpressive/xpressive.hpp>
static void regex_xpressive(benchmark::State& state) {
const auto flags = boost::xpressive::regex_constants::nosubs | boost::xpressive::regex_constants::optimize;
const auto re = boost::xpressive::sregex::compile(PATTERN, flags);
for (auto _ : state) {
const auto result = boost::xpressive::regex_match(g_s, re);
benchmark::DoNotOptimize(result);
}
}
BENCHMARK(regex_xpressive);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment