From 5a98b0ff251fbbdbddea7f85f110230c07f4e953 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 25 Oct 2024 10:04:36 +0200 Subject: [PATCH] Add speedtest for shuffle, plus a speedup in shuffle itself --- pdns/Makefile.am | 1 + pdns/shuffle.cc | 5 +++-- pdns/speedtest.cc | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 2522839a0f3c..2768e40b2220 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -964,6 +964,7 @@ speedtest_SOURCES = \ qtype.cc \ rcpgenerator.cc rcpgenerator.hh \ sillyrecords.cc \ + shuffle.cc shuffle.hh \ speedtest.cc \ statbag.cc \ svc-records.cc svc-records.hh \ diff --git a/pdns/shuffle.cc b/pdns/shuffle.cc index 1fbc004cf920..15eee7b6f4ec 100644 --- a/pdns/shuffle.cc +++ b/pdns/shuffle.cc @@ -157,10 +157,11 @@ unsigned int pdns::dedup(vector& rrs) unsigned int counter = 0; unsigned int numDups = 0; + seen.reserve(rrs.size()); for (const auto& rec : rrs) { - const auto key = rec.getContent()->wireFormatContent(rec.d_name, true, true); + auto key = rec.getContent()->wireFormatContent(rec.d_name, true, true); // This ignores class, ttl and place by using constants for those - if (!seen.emplace(key).second) { + if (!seen.emplace(std::move(key)).second) { dups[counter] = true; numDups++; } diff --git a/pdns/speedtest.cc b/pdns/speedtest.cc index 976275c3a1a1..2c77337bc72d 100644 --- a/pdns/speedtest.cc +++ b/pdns/speedtest.cc @@ -14,6 +14,7 @@ #include "lock.hh" #include "dns_random.hh" #include "arguments.hh" +#include "shuffle.hh" #if defined(HAVE_LIBSODIUM) #include @@ -1181,6 +1182,47 @@ struct SipHashTest }; #endif +struct DedupRecordsTest +{ + explicit DedupRecordsTest(size_t howmany, bool dedup, bool withdup = false) : d_howmany(howmany), d_dedup(dedup), d_withdup(withdup) + { + } + + [[nodiscard]] string getName() const + { + return std::to_string(d_howmany) + " DedupRecords" + std::string(d_dedup ? "" : " (generate only)") + + std::string(d_withdup ? " (with dup)" : ""); + } + + void operator()() const + { + std::vector vec; + vec.reserve(d_howmany); + std::string name("some.name.in.some.domain"); + auto count = d_howmany; + if (d_withdup) { + count--; + } + for (size_t i = 0; i < count; i++) { + auto content = DNSRecordContent::make(QType::TXT, QClass::IN, "\"a text " + std::to_string(i) + "\""); + DNSRecord rec(name, content, QType::TXT); + if (i == 0 && d_withdup) { + vec.emplace_back(rec); + } + vec.emplace_back(std::move(rec)); + } + + if (d_dedup) { + pdns::dedup(vec); + } + } + +private: + size_t d_howmany; + bool d_dedup; + bool d_withdup; +}; + int main() { try { @@ -1335,6 +1377,15 @@ int main() #ifdef HAVE_LIBSODIUM doRun(SipHashTest("a string of chars")); #endif + doRun(DedupRecordsTest(2, false)); + doRun(DedupRecordsTest(2, true)); + doRun(DedupRecordsTest(2, true, true)); + doRun(DedupRecordsTest(256, false)); + doRun(DedupRecordsTest(256, true)); + doRun(DedupRecordsTest(256, true, true)); + doRun(DedupRecordsTest(4096, false)); + doRun(DedupRecordsTest(4096, true)); + doRun(DedupRecordsTest(4096, true, true)); cerr<<"Total runs: " << g_totalRuns<