C#Enum.HasFlag与按位AND运算符检查 [英] C# Enum.HasFlag vs. Bitwise AND Operator Check
问题描述
如果您有用于位标志的enum
,即
If you have an enum
that is used for bit flags, i.e.,
[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);
或要做..
bool hasFlag = myFlagsEnum & _flagsEnum.Option1 != 0
如果检查多个标志之间存在性能差异,则也要考虑到这一点.
If there's a performance difference between checking multiple flags, then take that into account as well.
通常我会检查参考源,但是在这种情况下,Enum.HasFlags只是转到外部InternalHasFlags,所以我不知道它在做什么.
Normally I'd check out the reference source, but in this case Enum.HasFlags just goes to an extern InternalHasFlags, so I have no idea what it's doing.
推荐答案
使用HasFlag
会降低性能,因为该实现会验证您传递的enum
值与该标志的类型相同.
There is a performance cost to using HasFlag
, because the implementation verifies that the enum
value that you pass is of the same type as the flag.
由于没有这种区别,因此对实现进行了高度优化,以避免将较短的类型(例如byte
)提升为int
:
With this difference out of the way, the implementation is highly optimized to avoid promoting shorter types, such as byte
, to int
:
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
的来源可以在此处找到.
尽管成本相对较高,但除了最极端的情况外,这无关紧要.我建议保留它,除非您的探查器指出此调用是程序中的最大瓶颈.
Although the cost is relatively high, it is unlikely to matter, except for the most extreme situations. I would recommend keeping it, unless your profiler points to this call as a largest bottleneck in your program.
这篇关于C#Enum.HasFlag与按位AND运算符检查的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!