Optimize Uuid.ToString() by avoiding using sprintf to do the basic string transformation (#5925)
* Optimize Uuid.ToString() to use a cached value on multiple calls. * Add tests which call ToString() multiple times. * Optimize Uuid::ToString by avoiding using sprintf. * Assert all byte values will fit into a hex character. * Update comment in test.
This commit is contained in:
parent
ef538101f2
commit
d8b555a670
@ -3,6 +3,8 @@
|
||||
|
||||
#include "azure/core/uuid.hpp"
|
||||
|
||||
#include "azure/core/azure_assert.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <random>
|
||||
|
||||
@ -16,35 +18,41 @@ static thread_local std::mt19937_64 randomGenerator(std::random_device{}());
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
static char ByteToHexChar(uint8_t byte)
|
||||
{
|
||||
if (byte <= 9)
|
||||
{
|
||||
return '0' + byte;
|
||||
}
|
||||
|
||||
AZURE_ASSERT_MSG(
|
||||
byte >= 10 && byte <= 15,
|
||||
"It is expected, for a valid Uuid, to have byte values, where each of the two nibbles fit "
|
||||
"into a hexadecimal character");
|
||||
|
||||
return 'a' + (byte - 10);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace Azure { namespace Core {
|
||||
std::string Uuid::ToString() const
|
||||
{
|
||||
// Guid is 36 characters
|
||||
// Add one byte for the \0
|
||||
char s[37];
|
||||
std::string s(36, '-');
|
||||
|
||||
std::snprintf(
|
||||
s,
|
||||
sizeof(s),
|
||||
"%2.2x%2.2x%2.2x%2.2x-%2.2x%2.2x-%2.2x%2.2x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
|
||||
m_uuid[0],
|
||||
m_uuid[1],
|
||||
m_uuid[2],
|
||||
m_uuid[3],
|
||||
m_uuid[4],
|
||||
m_uuid[5],
|
||||
m_uuid[6],
|
||||
m_uuid[7],
|
||||
m_uuid[8],
|
||||
m_uuid[9],
|
||||
m_uuid[10],
|
||||
m_uuid[11],
|
||||
m_uuid[12],
|
||||
m_uuid[13],
|
||||
m_uuid[14],
|
||||
m_uuid[15]);
|
||||
for (size_t i = 0, j = 0; j < s.size() && i < UuidSize; i++)
|
||||
{
|
||||
if (i == 4 || i == 6 || i == 8 || i == 10)
|
||||
{
|
||||
j++; // Add hyphens at the appropriate places
|
||||
}
|
||||
|
||||
return std::string(s);
|
||||
uint8_t highNibble = (m_uuid[i] >> 4) & 0x0F;
|
||||
uint8_t lowNibble = m_uuid[i] & 0x0F;
|
||||
s[j++] = ByteToHexChar(highNibble);
|
||||
s[j++] = ByteToHexChar(lowNibble);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
Uuid Uuid::CreateUuid()
|
||||
|
||||
@ -16,12 +16,32 @@ TEST(Uuid, Basic)
|
||||
EXPECT_EQ(uuid.ToString().length(), 36);
|
||||
}
|
||||
|
||||
TEST(Uuid, Roundtrip)
|
||||
{
|
||||
std::array<uint8_t, 16U> uuidArray
|
||||
= {97, 126, 195, 45, 41, 178, 70, 23, 142, 131, 221, 245, 20, 45, 215, 15};
|
||||
|
||||
auto uuid = Uuid::CreateFromArray(uuidArray);
|
||||
std::string uuidString = uuid.ToString();
|
||||
std::string expectedString = "617ec32d-29b2-4617-8e83-ddf5142dd70f";
|
||||
EXPECT_EQ(expectedString, uuidString);
|
||||
|
||||
auto roundTrip = uuid.AsArray();
|
||||
EXPECT_EQ(uuidArray, roundTrip);
|
||||
}
|
||||
|
||||
TEST(Uuid, Transparent)
|
||||
{
|
||||
auto uuid1 = Uuid::CreateUuid();
|
||||
auto arrayUuid1(uuid1.AsArray());
|
||||
auto uuid2 = Azure::Core::Uuid::CreateFromArray(arrayUuid1);
|
||||
EXPECT_EQ(uuid1.ToString(), uuid2.ToString());
|
||||
|
||||
// Repeated calls of ToString() to validate the same values are returned, whether it is cached or
|
||||
// not.
|
||||
EXPECT_EQ(uuid1.ToString(), uuid2.ToString());
|
||||
EXPECT_EQ(uuid1.ToString(), uuid1.ToString());
|
||||
EXPECT_EQ(uuid2.ToString(), uuid2.ToString());
|
||||
}
|
||||
|
||||
TEST(Uuid, Randomness)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user