Commit 26b552bc authored by Stian Jakobsen's avatar Stian Jakobsen
Browse files

Merge kmp_fix into master

parent f38e1ccf
......@@ -21,25 +21,28 @@ namespace alg = dte3603::string_match::algorithms;
BENCHMARK_DEFINE_F(HelloWorldF, stlSearch)
(benchmark::State& st)
{
for (auto const& _ : st)
std::search(m_string.begin(), m_string.end(), m_sequence.begin(),
m_sequence.end());
for (auto const& _ : st) {
benchmark::DoNotOptimize(std::search(m_string.begin(), m_string.end(),
m_sequence.begin(), m_sequence.end()));
}
}
BENCHMARK_DEFINE_F(HelloWorldF, naiveSearch)
(benchmark::State& st)
{
for (auto const& _ : st)
alg::naive_search(m_string.begin(), m_string.end(), m_sequence.begin(),
m_sequence.end());
for (auto const& _ : st) {
benchmark::DoNotOptimize(alg::naive_search(
m_string.begin(), m_string.end(), m_sequence.begin(), m_sequence.end()));
}
}
BENCHMARK_DEFINE_F(HelloWorldF, kmpSearch)
(benchmark::State& st)
{
for (auto const& _ : st)
alg::kmp_search(m_string.begin(), m_string.end(), m_sequence.begin(),
m_sequence.end());
for (auto const& _ : st) {
benchmark::DoNotOptimize(alg::kmp_search(
m_string.begin(), m_string.end(), m_sequence.begin(), m_sequence.end()));
}
}
// LongShort
BENCHMARK_DEFINE_F(LongTextShortPattern, stlSearch)(benchmark::State& st)
......@@ -64,45 +67,59 @@ BENCHMARK_DEFINE_F(LongTextShortPattern, kmpSearch)(benchmark::State& st)
// LongLong
BENCHMARK_DEFINE_F(LongTextLongPattern, stlSearch)(benchmark::State& st)
BENCHMARK_DEFINE_F(LongStringShortPatternF, stlSearch)
(benchmark::State& st)
{
for (auto const& _ : st)
std::search(m_string.begin(), m_string.end(), m_sequence.begin(),
m_sequence.end());
for (auto const& _ : st) {
benchmark::DoNotOptimize(std::search(m_string.begin(), m_string.end(),
m_sequence.begin(), m_sequence.end()));
}
}
BENCHMARK_DEFINE_F(LongTextLongPattern, naiveSearch)(benchmark::State& st)
BENCHMARK_DEFINE_F(LongStringShortPatternF, naiveSearch)
(benchmark::State& st)
{
for (auto const& _ : st)
alg::naive_search(m_string.begin(), m_string.end(), m_sequence.begin(),
m_sequence.end());
for (auto const& _ : st) {
benchmark::DoNotOptimize(alg::naive_search(
m_string.begin(), m_string.end(), m_sequence.begin(), m_sequence.end()));
}
}
BENCHMARK_DEFINE_F(LongTextLongPattern, kmpSearch)(benchmark::State& st)
BENCHMARK_DEFINE_F(LongStringShortPatternF, kmpSearch)
(benchmark::State& st)
{
for (auto const& _ : st)
alg::kmp_search(m_string.begin(), m_string.end(), m_sequence.begin(),
m_sequence.end());
for (auto const& _ : st) {
benchmark::DoNotOptimize(alg::kmp_search(
m_string.begin(), m_string.end(), m_sequence.begin(), m_sequence.end()));
}
}
// ShortShort
BENCHMARK_DEFINE_F(ShortTextShortPattern, stlSearch)(benchmark::State& st)
BENCHMARK_DEFINE_F(LongStringLongPatternF, stlSearch)
(benchmark::State& st)
{
for (auto const& _ : st)
std::search(m_string.begin(), m_string.end(), m_sequence.begin(),
m_sequence.end());
for (auto const& _ : st) {
benchmark::DoNotOptimize(std::search(m_string.begin(), m_string.end(),
m_sequence.begin(), m_sequence.end()));
}
}
BENCHMARK_DEFINE_F(ShortTextShortPattern, naiveSearch)(benchmark::State& st)
BENCHMARK_DEFINE_F(LongStringLongPatternF, naiveSearch)
(benchmark::State& st)
{
for (auto const& _ : st)
alg::naive_search(m_string.begin(), m_string.end(), m_sequence.begin(),
m_sequence.end());
for (auto const& _ : st) {
benchmark::DoNotOptimize(alg::naive_search(
m_string.begin(), m_string.end(), m_sequence.begin(), m_sequence.end()));
}
}
BENCHMARK_DEFINE_F(ShortTextShortPattern, kmpSearch)(benchmark::State& st)
BENCHMARK_DEFINE_F(LongStringLongPatternF, kmpSearch)
(benchmark::State& st)
{
for (auto const& _ : st)
alg::kmp_search(m_string.begin(), m_string.end(), m_sequence.begin(),
m_sequence.end());
for (auto const& _ : st) {
benchmark::DoNotOptimize(alg::kmp_search(
m_string.begin(), m_string.end(), m_sequence.begin(), m_sequence.end()));
}
}
// Register Benchmark
......@@ -112,34 +129,28 @@ BENCHMARK_REGISTER_F(HelloWorldF, naiveSearch);
BENCHMARK_REGISTER_F(HelloWorldF, kmpSearch);
BENCHMARK_REGISTER_F(LongTextShortPattern, stlSearch)
BENCHMARK_REGISTER_F(LongStringShortPatternF, stlSearch)
->RangeMultiplier(10)
->Range(1e1, 1e6);
->Range(1e1, 1e7);
BENCHMARK_REGISTER_F(LongTextShortPattern, naiveSearch)
BENCHMARK_REGISTER_F(LongStringShortPatternF, naiveSearch)
->RangeMultiplier(10)
->Range(1e1, 1e6);
->Range(1e1, 1e7);
BENCHMARK_REGISTER_F(LongTextShortPattern, kmpSearch)
BENCHMARK_REGISTER_F(LongStringShortPatternF, kmpSearch)
->RangeMultiplier(10)
->Range(1e1, 1e6);
->Range(1e1, 1e7);
BENCHMARK_REGISTER_F(LongTextLongPattern, stlSearch)
BENCHMARK_REGISTER_F(LongStringLongPatternF, stlSearch)
->RangeMultiplier(10)
->Range(1e1, 1e6);
->Range(1e1, 1e7);
BENCHMARK_REGISTER_F(LongTextLongPattern, naiveSearch)
BENCHMARK_REGISTER_F(LongStringLongPatternF, naiveSearch)
->RangeMultiplier(10)
->Range(1e1, 1e6);
->Range(1e1, 1e7);
BENCHMARK_REGISTER_F(LongTextLongPattern, kmpSearch)
BENCHMARK_REGISTER_F(LongStringLongPatternF, kmpSearch)
->RangeMultiplier(10)
->Range(1e1, 1e6);
BENCHMARK_REGISTER_F(ShortTextShortPattern, stlSearch);
BENCHMARK_REGISTER_F(ShortTextShortPattern, naiveSearch);
BENCHMARK_REGISTER_F(ShortTextShortPattern, kmpSearch);
->Range(1e1, 1e7);
BENCHMARK_MAIN();
......@@ -5,9 +5,27 @@
#include <iterator>
#include <algorithm>
#include <span>
#include <vector>
namespace dte3603::string_match::algorithms
{
// helper method for creating the lookup table
std::vector<int> create_lps(auto pattern_size, auto pattern_span, auto pred)
{
std::vector<int> lookup_table(pattern_size, 0);
// advancing through the pattern building our lookup table
for (auto i = 1, j = 0; i < pattern_size; i++) {
if (pred(pattern_span[i], pattern_span[j])) {
lookup_table[i] = j++;
}
else if (j != 0) {
j = lookup_table[j - 1];
i -= 1;
}
}
return lookup_table;
}
template <std::forward_iterator Iterator_T, std::forward_iterator Sentinel_T,
std::forward_iterator S_Iterator_T,
......@@ -23,42 +41,42 @@ namespace dte3603::string_match::algorithms
auto const string_size = string_span.size();
auto const pattern_size = pattern_span.size();
auto lookup_table = new int[pattern_size];
lookup_table[0] = 0;
int i = 0;
// Creating the lookup table
auto lookup_table = create_lps(pattern_size, pattern_span, pred);
// filling our lookup table based on the pattern
for (auto j = 0; j < pattern_size; j++) {
while (i > 0 && !pred(pattern_span[i], pattern_span[j])) {
i = lookup_table[j - 1];
}
if (pred(pattern_span[i], pattern_span[j])) {
i = i + 1;
}
lookup_table[j] = i;
}
// Doing naive search again with a modified fail case.
if (string_size >= pattern_size) {
// Iterating for string from start to end by string_size
for (auto i = 0; i < string_size; i++) {
auto count = 0;
auto current_pos = i;
auto count = 0;
// Iterating over the pattern to match with current string pos
for (auto j = 0; j < pattern_size; j++) {
if (!pred(string_span[current_pos], pattern_span[j])) {
// when failing, only do lookup table when j isn't 0 then continue
// of for, otherwise break
if (pred(string_span[current_pos], pattern_span[j])) {
count++;
current_pos++;
}
else {
// when failing, only do lookup table when j isn't 0, otherwise
// break
if (j != 0) {
j = lookup_table[j - 1];
continue;
auto pos = lookup_table[j - 1];
if (pos == 0) {
break;
}
j = pos - 1;
}
break;
else {
break;
}
}
// Full match found, returning begin iterator advanced to starting
// position of match (i)
if (count == pattern_size) {
return begin + i;
}
// match found, advancing
count++;
current_pos++;
}
// full match found, return begin iterator advanced to the starting
// position of the match found.
// Full match found, returning begin iterator advanced to starting
// position of match (i)
if (count == pattern_size) {
return begin + i;
}
......@@ -67,6 +85,8 @@ namespace dte3603::string_match::algorithms
return end;
}
} // namespace dte3603::string_match::algorithms
#endif // DTE3603_WEEK1_STRING_MATCH_KNUTH_MORRIS_PRATT_SEARCH_H
......@@ -41,51 +41,37 @@ namespace dte3603::predef::benchmarking::string_match::fixtures
}
};
struct LongTextShortPattern : detail::StringMatchBenchmarkFixtureTemplate {
struct LongStringShortPatternF : detail::StringMatchBenchmarkFixtureTemplate {
using Base = detail::StringMatchBenchmarkFixtureTemplate;
using Base::Base;
~LongTextShortPattern() override {}
~LongStringShortPatternF() override {}
void SetUp(const benchmark::State& st) final
void SetUp([[maybe_unused]] const benchmark::State& st) final
{
m_string = "AABBCCDDEEFF";
for (auto i = 0; i < st.range(0); i++) {
m_string.append("aabbccaaffee");
auto const n = st.range(0);
int j = n;
for (auto i = 0; i < j; i++) {
m_string.append("aabccaaaab");
}
m_string.append("aaagttseeeewwtwdq");
m_sequence = "aaagttseeeewwtwdq";
m_string.append("aabcaaaacaaabbbcaab");
m_sequence.append("aabcaaaacaaabbbcaab");
}
};
struct ShortTextShortPattern : detail::StringMatchBenchmarkFixtureTemplate {
struct LongStringLongPatternF : detail::StringMatchBenchmarkFixtureTemplate {
using Base = detail::StringMatchBenchmarkFixtureTemplate;
using Base::Base;
~ShortTextShortPattern() override {}
~LongStringLongPatternF() override {}
void SetUp(const benchmark::State& st) final
{
m_string = "AABBCCDDEEFF";
m_string.append("aaagttseeeewwtwdq");
m_sequence = "aaagttseeeewwtwdq";
}
};
struct LongTextLongPattern : detail::StringMatchBenchmarkFixtureTemplate {
using Base = detail::StringMatchBenchmarkFixtureTemplate;
using Base::Base;
~LongTextLongPattern() override {}
void SetUp(const benchmark::State& st) final
void SetUp([[maybe_unused]] const benchmark::State& st) final
{
m_string = "AABBCCDDEEFF";
for (auto i = 0; i < st.range(0); i++) {
m_string.append("aabbccaaffee");
auto const n = st.range(0);
for (auto i = 0; i < n; i++) {
m_string.append("aabccaaaab");
m_sequence.append("aabccaaaab");
}
m_string.append("aaagttseeeewwtwdq");
m_sequence = m_string;
m_string.append("aabcaaaacaaacaab");
m_sequence.append("aabcaaaacaaacaab");
}
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment