Skip to content

Commit

Permalink
More refinements
Browse files Browse the repository at this point in the history
  • Loading branch information
ZehMatt committed Nov 7, 2024
1 parent 07dfa78 commit 85605fa
Show file tree
Hide file tree
Showing 3 changed files with 242 additions and 75 deletions.
34 changes: 34 additions & 0 deletions benchmark/src/benchmarks/benchmark.stringpool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,40 @@ namespace zasm::benchmarks
}
BENCHMARK(BM_StringPool_Release)->Range(0, kTestSize)->Unit(benchmark::kMillisecond);

static void BM_StringPool_Reuse(benchmark::State& state)
{
StringPool pool;
for (auto _ : state)
{
std::vector<StringPool::Id> stringIds;

state.PauseTiming();
for (auto i = 0; i < state.range(0); ++i)
{
const auto& str = kInputStrings[i];

auto stringId = pool.aquire(str);
stringIds.push_back(stringId);
}

// Clear.
for (auto i = 0; i < state.range(0); ++i)
{
auto stringId = pool.release(stringIds[i]);
}
state.ResumeTiming();

for (auto i = 0; i < state.range(0); ++i)
{
const auto& str = kInputStrings[i];

auto stringId = pool.aquire(str);
benchmark::DoNotOptimize(stringId);
}
}
}
BENCHMARK(BM_StringPool_Reuse)->Range(0, kTestSize)->Unit(benchmark::kMillisecond);

static void BM_StringPool_Get(benchmark::State& state)
{
StringPool pool;
Expand Down
124 changes: 113 additions & 11 deletions tests/src/tests/tests.stringpool.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <gtest/gtest.h>
#include <random>

#define IN_TESTS
#include <zasm/core/stringpool.hpp>
Expand Down Expand Up @@ -84,22 +85,36 @@ namespace zasm::tests

const auto id5 = pool.aquire(str5);
ASSERT_NE(id5, StringPool::Id::Invalid);
ASSERT_NE(id5, id1);
ASSERT_EQ(id5, id1);
ASSERT_EQ(pool.getLength(id5), std::size(str5) - 1);
ASSERT_EQ(pool.getRefCount(id5), 1);
}

TEST(StringPoolTests, TestManyStrings)
{
StringPool pool;
constexpr auto kTestSize = 100'000;

std::vector<StringPool::Id> ids;
static constexpr const char kChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

constexpr auto kTestSize = 1'000'000;
for (auto i = 0U; i < kTestSize; i++)
static const std::vector<std::string> kInputStrings = []() {
std::vector<std::string> strings;
std::set<std::string> uniqueStrings;
std::mt19937 prng(42);
while (uniqueStrings.size() < kTestSize)
{
std::string str = std::string("hello") + std::to_string(i);
std::string str;
for (size_t i = 0; i < 4 + (prng() % 24); ++i)
{
str.push_back(kChars[prng() % (sizeof(kChars) - 1)]);
}
uniqueStrings.emplace(std::move(str));
}
strings.insert(strings.end(), uniqueStrings.begin(), uniqueStrings.end());
return strings;
}();

const auto fillPool = [](StringPool& pool, std::vector<StringPool::Id>& ids) {
ids.clear();
for (const auto& str : kInputStrings)
{
const auto id = pool.aquire(str);
ASSERT_NE(id, StringPool::Id::Invalid);
ASSERT_EQ(pool.getLength(id), str.size());
Expand All @@ -111,16 +126,103 @@ namespace zasm::tests

ids.push_back(id);
}
ASSERT_EQ(ids.size(), kInputStrings.size());
};

TEST(StringPoolTests, TestManyStrings)
{
StringPool pool;
std::vector<StringPool::Id> ids;

fillPool(pool, ids);

// Validate that the contents still match.
for (auto i = 0U; i < kTestSize; i++)
for (size_t i = 0; i < kTestSize; i++)
{
std::string str = std::string("hello") + std::to_string(i);

const auto& str = kInputStrings[i];
const auto* cstr = pool.get(ids[i]);
ASSERT_NE(cstr, nullptr);
ASSERT_EQ(strcmp(cstr, str.c_str()), 0);
}
}

TEST(StringPoolTests, TestClearIndividually)
{
StringPool pool;
std::vector<StringPool::Id> ids;

fillPool(pool, ids);

// Clear.
for (auto id : ids)
{
ASSERT_EQ(pool.release(id), 0);
}

ASSERT_EQ(pool.size(), 0);
}

TEST(StringPoolTests, TestReuseSingle)
{
StringPool pool;
std::vector<StringPool::Id> ids;

fillPool(pool, ids);

// Validate strings.
for (auto i = 0U; i < kTestSize; i++)
{
const auto& str = kInputStrings[i];

const auto* cstr = pool.get(ids[i]);
ASSERT_NE(cstr, nullptr) << "i = " << i;
ASSERT_EQ(strcmp(cstr, str.c_str()), 0) << "i = " << i;
}

// Clear.
for (auto id : ids)
{
ASSERT_EQ(pool.release(id), 0);
}

fillPool(pool, ids);

// Validate strings.
for (auto i = 0U; i < kTestSize; i++)
{
const auto& str = kInputStrings[i];

const auto* cstr = pool.get(ids[i]);
ASSERT_NE(cstr, nullptr) << "i = " << i;
ASSERT_EQ(strcmp(cstr, str.c_str()), 0) << "i = " << i;
}
}

TEST(StringPoolTests, TestReuseMultiple)
{
StringPool pool;
std::vector<StringPool::Id> ids;

for (size_t i = 0; i < 5; i++)
{
fillPool(pool, ids);

// Validate that the contents still match.
for (auto i = 0U; i < kTestSize; i++)
{
const auto& str = kInputStrings[i];

const auto* cstr = pool.get(ids[i]);
ASSERT_NE(cstr, nullptr);
ASSERT_EQ(strcmp(cstr, str.c_str()), 0);
}

// Clear.
for (auto id : ids)
{
ASSERT_EQ(pool.release(id), 0);
}
}
}

} // namespace zasm::tests
Loading

0 comments on commit 85605fa

Please sign in to comment.