2016-09-14 8 views
2

あなたはビットフラグのために使用されているenum、すなわちを持っている場合は、ビット単位の対C#Enum.HasFlag、オペレータのチェック

[Flags] 
internal enum _flagsEnum : byte 
{ 
    None = 0,   //00000000 
    Option1 = 1,  //00000001 
    Option2 = 1 << 1, //00000010 
    Option3 = 1 << 2, //00000100 
    Option4 = 1 << 3, //00001000 
    Option5 = 1 << 4, //00010000 
    Option6 = 1 << 5, //00100000 
    Option7 = 1 << 6, //01000000 
    Option8 = 1 << 7, //10000000 
    All = Byte.MaxValue,//11111111 
} 

_flagsEnum myFlagsEnum = _flagsEnum.None; 

が、それはより速く行うことです。..

bool hasFlag = myFlagsEnum.HasFlag(_flagsEnum.Option1); 

かへdo ..

bool hasFlag = myFlagsEnum & _flagsEnum.Option1 != 0 

複数のフラグをチェックする際にパフォーマンスの違いがある場合は、それも考慮してください。

通常、私はリファレンスソースをチェックアウトしますが、この場合Enum.HasFlagsはextern InternalHasFlagsに行くので、何をしているのか分かりません。

+2

パフォーマンスコストがあります。参照してください:http://stackoverflow.com/questions/7368652/what-is-it-that-makes-enum-hasflag-so-slow –

+1

早すぎる最適化のようです。私が 'HasFlag'について気に入らないことの1つは、同じタイプのものではなく、引数として' enum'オブジェクトを受け入れることです。 –

+1

'HasFlag'は単純なビット単位のチェック以上のことを行いますhttp://blogs.microsoft.co.il/bnaya/2011/01/28/enumhasflag-good-or-bad/ –

答えて

2

HasFlagを使用するとパフォーマンスが低下します。これは、渡されたenumの値がフラグと同じ型であることを実装が検証するためです。 、実装が非常にintに短いタイプは、そのような編byteを促進避けるために最適化された方法のうち、この差が

switch (pMTThis->GetNumInstanceFieldBytes()) { 
case 1: 
    cmp = ((*(UINT8*)pThis & *(UINT8*)pFlags) == *(UINT8*)pFlags); 
    break; 
case 2: 
    cmp = ((*(UINT16*)pThis & *(UINT16*)pFlags) == *(UINT16*)pFlags); 
    break; 
case 4: 
    cmp = ((*(UINT32*)pThis & *(UINT32*)pFlags) == *(UINT32*)pFlags); 
    break; 
case 8: 
    cmp = ((*(UINT64*)pThis & *(UINT64*)pFlags) == *(UINT64*)pFlags); 
    break; 
default: 
    // should not reach here. 
    UNREACHABLE_MSG("Incorrect Enum Type size!"); 
    break; 
} 

ReflectionEnum::InternalHasFlagのソースはhereを見つけることができます。

コストは比較的高いものの、最も極端な状況を除いては問題にはなりません。プロファイラがこの呼び出しをあなたのプログラムの最大のボトルネックとして指摘しない限り、私はそれを保持することをお勧めします。

+0

ああ、私はCLRの現在オープンソースをチェックしようと思っていたはずです - 私はまだそれに慣れていないと思います! – Yushatak

関連する問題