Reputation: 73041
I have this simple function in my program:
enum {
TABLE_INDEX_TYPE_UINT8 = 0,
TABLE_INDEX_TYPE_UINT16,
TABLE_INDEX_TYPE_UINT32,
};
// inline method
uint8_t MyTable :: GetTableIndexTypeForTableSize(uint32_t tableSize) const
{
// Deliberately testing for strictly-less-than-255/65535 here,
// because 255 and 65535 are used as special sentinel values
return (tableSize < 255) ? TABLE_INDEX_TYPE_UINT8
: ((tableSize < 65535) ? TABLE_INDEX_TYPE_UINT16 : TABLE_INDEX_TYPE_UINT32);
}
In the current version of my program, I call this method whenever tableSize
changes, and store the result in a member-variable for quick re-use, and that works fine.
However, today I am experimenting with reducing sizeof(MyTable)
, and one way to do that is to get rid of unnecessary member-variables. Since the cached result of the above function is always re-computable (based on the current value of the tableSize
member-variable), I modified the code to just call GetTableIndexTypeForTableSize(tableSize)
whenever it needs to instead.
That also works fine (and allows me reduce sizeof(MyTable)
by 4 bytes, yay), but it leads to a measurable (~5%) decrease in performance in my performance-benchmark test -- I believe that is because the current implementation of GetTableIndexForTableSize()
includes two branch-operations.
So my question is, is there a clever way to reimplement the above function such that it doesn't require any branching, and thus avoid the 5% slowdown? (I presume using a lookup-table would be a bad idea, since I'd be replacing branch-misprediction delays with RAM-access delays, making things even slower)
Upvotes: 2
Views: 299
Reputation: 9672
If you choose your enum values carefully, it should be possible to bitwise or yourself to the right enum value. I doubt it will be much that quicker though.
#include <cstdint>
enum {
TABLE_INDEX_TYPE_UINT8 = 0,
TABLE_INDEX_TYPE_UINT16 = 1,
TABLE_INDEX_TYPE_UINT32 = 3
};
uint8_t MyTable::GetTableIndexTypeForTableSize(uint32_t tableSize) const
{
return (tableSize >= 255) | ( (tableSize >= 65535) << 1 );
}
Upvotes: 6