I need to convert the ENUM to a respective string value for which I came up with two approaches and I'm trying to see why would a second approach be better than the first one if even in terms of performance and practicality?
Both approaches work. The second requires additional work of having to create an array of struct whereas the first approach merely uses a switch case with hardcoded string values of the corresponding enum.
First approach
enum class Num : uint32_t
{
One,
Two,
Three
};
string EnumToStr(Num num)
{
switch (num)
{
case Num::One:
return "One";
break;
case Num::Two:
return "Two";
break;
case Num::Three:
return "Three";
break;
default:
return "";
}
}
int main()
{
cout << EnumToStr(Num::One) << endl; // ONE
return 0;
}
Second Approach
#define ENTRY(x) {x, #x}
enum class Num : uint32_t
{
One,
Two,
Three,
MAX
};
struct Lookup
{
Num num;
std::string_view str;
};
constexpr static Lookup table[] =
{
ENTRY(Num::One),
ENTRY(Num::Two),
ENTRY(Num::Three)
};
string_view GetStr(Num num)
{
uint32_t entryIndex = static_cast<uint32_t>(num);
uint32_t maxNum = static_cast<uint32_t>(Num::MAX);
if (entryIndex < 0 || entryIndex > maxNum)
{
return "";
}
return table[entryIndex].str;
}
int main()
{
cout << GetStr(Num::One) << endl; // Num::ONE
return 0;
}
An additional thought that #define ENTRY(x) {x, #x}
may be not a recommended approach in C++. Are there better ways around it?
Edit:
The following is what I came up with for the memory consumption for respective functions. It seems the second approach consumes more owing to the struct table
in particular.
Second Approach:
- Looking at the asm,
GetStr()
consumes (0x401147- 0x401120)+1 = 40 bytes sizeof(table)
= 72 bytes- total = 72 + 40 = 112 bytes
First Approach:
- Looking at the asm,
SwitchCase()
consumes (0x40116d- 0x401120)+1 = 78 bytes
However, doing the following resulted in Second Approach consuming lesser bytes than the First:
If
const char *
is used instead ofstring_view
Adding more enum entries
{gcc12.1 + O3} 166 bytes of First Approach vs 96 bytes of Second Approach (#bytes are calculated at the bottom comments)
So with more enum entries, does the Second Approach outperform the First Approach?
Is this one way of determining the performance of functions?
using namespace std;
?std::endl
? You don't have to break out all the bad ideas. \$\endgroup\$