From 23a8c007a668413c2e8cbd00984d223ed5ecfe05 Mon Sep 17 00:00:00 2001 From: Louis Wilson Date: Mon, 28 Oct 2019 17:20:14 -0700 Subject: [PATCH 1/4] Improve performance of string conversion Convert to string with one call to snprintf and no string concatenations instead of 5 calls to snprintf and 8 concatenations. Microbenchmarks indicate that this is approximately 17% faster (1.17 times as fast). --- src/guid.cpp | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/src/guid.cpp b/src/guid.cpp index 3061a9b..bac10f9 100644 --- a/src/guid.cpp +++ b/src/guid.cpp @@ -113,27 +113,16 @@ bool Guid::isValid() const // convert to string using std::snprintf() and std::string std::string Guid::str() const { - char one[10], two[6], three[6], four[6], five[14]; - - snprintf(one, 10, "%02x%02x%02x%02x", - _bytes[0], _bytes[1], _bytes[2], _bytes[3]); - snprintf(two, 6, "%02x%02x", - _bytes[4], _bytes[5]); - snprintf(three, 6, "%02x%02x", - _bytes[6], _bytes[7]); - snprintf(four, 6, "%02x%02x", - _bytes[8], _bytes[9]); - snprintf(five, 14, "%02x%02x%02x%02x%02x%02x", + constexpr size_t guidSize = sizeof("01234567-0123-0123-0123-0123456789ab"); + char out[guidSize]; + snprintf(out, guidSize, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + _bytes[0], _bytes[1], _bytes[2], _bytes[3], + _bytes[4], _bytes[5], + _bytes[6], _bytes[7], + _bytes[8], _bytes[9], _bytes[10], _bytes[11], _bytes[12], _bytes[13], _bytes[14], _bytes[15]); - const std::string sep("-"); - std::string out(one); - out += sep + two; - out += sep + three; - out += sep + four; - out += sep + five; - - return out; + return std::string(out, guidSize - 1); } // conversion operator for std::string From 903c3510507300b64d1feabacf6008a13b35f7f3 Mon Sep 17 00:00:00 2001 From: Louis Wilson Date: Mon, 28 Oct 2019 18:00:37 -0700 Subject: [PATCH 2/4] Explicitly discard CoCreateGuid HRESULT On MSDN it is marked as only being able to return S_OK, but in combaseapi.h it is still marked _Check_result_. This will cause a warning if you have them cranked up high enough. --- src/guid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/guid.cpp b/src/guid.cpp index bac10f9..5352700 100644 --- a/src/guid.cpp +++ b/src/guid.cpp @@ -304,7 +304,7 @@ Guid newGuid() Guid newGuid() { GUID newId; - CoCreateGuid(&newId); + (void)CoCreateGuid(&newId); std::array bytes = { From 9b51a5daea6ad892c6e9830293214f39f2111acc Mon Sep 17 00:00:00 2001 From: Louis Wilson Date: Tue, 29 Oct 2019 15:09:19 -0700 Subject: [PATCH 3/4] Mark a couple functions static This could theoretically open up some optimizations, but mostly it's just good hygiene. --- src/guid.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/guid.cpp b/src/guid.cpp index 5352700..438b874 100644 --- a/src/guid.cpp +++ b/src/guid.cpp @@ -146,7 +146,7 @@ Guid::Guid(std::array &&bytes) : _bytes(std::move(bytes)) { } // converts a single hex char to a number (0 - 15) -unsigned char hexDigitToChar(char ch) +static unsigned char hexDigitToChar(char ch) { // 0-9 if (ch > 47 && ch < 58) @@ -163,7 +163,7 @@ unsigned char hexDigitToChar(char ch) return 0; } -bool isValidHexChar(char ch) +static bool isValidHexChar(char ch) { // 0-9 if (ch > 47 && ch < 58) @@ -181,7 +181,7 @@ bool isValidHexChar(char ch) } // converts the two hexadecimal characters to an unsigned char (a byte) -unsigned char hexPairToChar(char a, char b) +static unsigned char hexPairToChar(char a, char b) { return hexDigitToChar(a) * 16 + hexDigitToChar(b); } From 1ef5038cbbededd84d02a9df7814115613912ba9 Mon Sep 17 00:00:00 2001 From: Louis Wilson Date: Tue, 29 Oct 2019 15:40:22 -0700 Subject: [PATCH 4/4] Clearer names for locals --- src/guid.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/guid.cpp b/src/guid.cpp index 438b874..cb88c6e 100644 --- a/src/guid.cpp +++ b/src/guid.cpp @@ -113,16 +113,16 @@ bool Guid::isValid() const // convert to string using std::snprintf() and std::string std::string Guid::str() const { - constexpr size_t guidSize = sizeof("01234567-0123-0123-0123-0123456789ab"); - char out[guidSize]; - snprintf(out, guidSize, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + constexpr size_t guidBufferSize = sizeof("01234567-0123-0123-0123-0123456789ab"); + char buffer[guidBufferSize]; + snprintf(buffer, guidBufferSize, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", _bytes[0], _bytes[1], _bytes[2], _bytes[3], _bytes[4], _bytes[5], _bytes[6], _bytes[7], _bytes[8], _bytes[9], _bytes[10], _bytes[11], _bytes[12], _bytes[13], _bytes[14], _bytes[15]); - return std::string(out, guidSize - 1); + return std::string(buffer, guidBufferSize - 1); } // conversion operator for std::string