switch is not optimized for mapping between enums

M

MariuszC

Hello,
I have used some library where is defined enum like:

typedef enum Enum1 { ENUM1_1, ENUM1_2, ENUM1_3, ENUM1_4, ENUM1_5 };

In my code I have defined:

typedef enum Enum2 { ENUM2_1, ENUM2_2, ENUM2_3, ENUM2_4, ENUM2_5 };

My map function looks like:

Enum2 mapEnum1toEnum2( Enum1 enum )
{
switch( enum )
{
case ENUM1_1: return ENUM2_1;
case ENUM1_2: return ENUM2_2;
case ENUM1_3: return ENUM2_3;
case ENUM1_4: return ENUM2_4;
case ENUM1_5: return ENUM2_5;
default: throw "UNKNOWN ENUM1!!!";
}
}

I have analised asm code generated by compiler, and the results is not
optimal as it can be. Because the enums can map 1:1 I have expected that
compiler creates code similar to:

Enum2 mapEnum1toEnum2( Enum1 enum )
{
if ( enum < ENUM1_1 && enum > ENUM1_5 )
throw "UNKNOWN ENUM1!!!";
return reinterpret_cast<Enum2>( enum );
}

In example above both enums are continuous, but in case if one of enums
is not continuous there is another possibility - create hash table e.g.
typedef enum Enum2 { ENUM2_1 = -1, ENUM2_2 = 33, ENUM2_3 = 55, ENUM2_4 =
1234, ENUM2_5 = 5533 };

Enum2 mapEnum1toEnum2( Enum1 enum )
{
static const Enum2 hash[] = { ENUM2_1, ENUM2_2, ENUM2_3, ENUM2_4,
ENUM2_5 };
if ( enum < ENUM1_1 && enum > ENUM1_5 )
throw "UNKNOWN ENUM1!!!";
return hash[enum];
}


Do you know any implementation to create mapEnum1toEnum2 function which
is better optimized than switch construction. Maybe there is possible
to use metaprogramming for this issue.

Best Regards
MariuszC
 
A

Andrey Tarasevich

MariuszC said:
...
Do you know any implementation to create mapEnum1toEnum2 function which
is better optimized than switch construction.

Microsoft Visual C++ compiler that comes with MS Visual Studio 6 will
compile this into a jump instruction with run-time calculated
destination address

00401000 mov eax,dword ptr [esp+4]
00401004 cmp eax,4
00401007 ja 0040102b
00401009 jmp dword ptr [eax*4+401044h]
00401010 xor eax,eax
00401012 ret
00401013 mov eax,1
00401018 ret
00401019 mov eax,2
0040101E ret
0040101F mov eax,3
00401024 ret
00401025 mov eax,4
0040102A ret
0040102B ... ; throw is implemented here

The "unsigned" conditional jump instruction 'ja' covers both 'enum <
ENUM1_1' and 'enum > ENUM1_5' cases (it jumps to the 'throw' portion of
the code).

The conversion is not implemented exactly as 'reinterpret_cast', but it
is still more efficient than a chain of comparisons.

What exactly did you get in your case?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,818
Latest member
SapanaCarpetStudio

Latest Threads

Top