From 19a0a3a359d7106e06da6fce67e9c09cd1d17b31 Mon Sep 17 00:00:00 2001 From: Andrea Pappacoda Date: Fri, 26 Aug 2022 12:53:42 +0200 Subject: [PATCH] perf: optimize GenerateRandomString() (#66) The previous implementation used an std::stringstream to concatenate the generated random string. The new one uses a simple preallocated std::string, as the size of the output is already known - it is the length parameter. It also uses std::generate_n() instead of an explicit loop, making the code more concise and potentially faster, as no calls to std::string::operator+= are needed. Calling GenerateRandomString(1'000'000) with the std::stringstream-based implementation allocated 16 times, for a total of 3'173'516 bytes. The new one cuts this down to 4 allocs, for a total of 1'076'864 bytes. --- src/util/helpers/helpers.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/util/helpers/helpers.cpp b/src/util/helpers/helpers.cpp index dfc36975..2a076aca 100644 --- a/src/util/helpers/helpers.cpp +++ b/src/util/helpers/helpers.cpp @@ -419,18 +419,20 @@ std::string GenerateRandomString(size_t length) return GenerateRandomString(length, kCharacters); } -std::string GenerateRandomString(size_t length, std::string_view characters) +std::string GenerateRandomString(const size_t length, const std::string_view characters) { assert(!characters.empty()); - std::stringstream result; + std::string result; + result.resize(length); std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution index_dist(0, characters.size() - 1); - for (uint32_t i = 0; i < length; ++i) - { - result << characters[index_dist(gen)]; - } + std::generate_n( + result.begin(), + length, + [&] { return characters[index_dist(gen)]; } + ); - return result.str(); -} \ No newline at end of file + return result; +}