数组#Contain与OR逻辑与switch语句的性能
本文关键字:语句 switch 性能 #Contain OR 数组 | 更新日期: 2023-09-27 17:59:41
其中哪个最快,哪个最慢(C#)?
// Array#Contain
int i = ...;
if ((new int[] { 0, 1, 3, 7, ... }).Contains(i))
{
...
}
// OR logic
int i = ...;
if (i == 0 || i == 1 || i == 3 || i == 7 || ...)
{
...
}
// switch statement
int i = ...;
switch(i)
{
case 0:
case 1:
case 3:
case 7:
...
...
break;
}
这些东西的性能取决于目标机器体系结构,可能还取决于操作系统
对于x86/x64机器,我认为上面的代码应该由JIT翻译成以下等效的汇编程序:
-
Array.Contains
方法lea EDI, [...] mov ECX, sizeof(...) repne scasd
-
if
语句中的顺序OR
smov EAX, ... cmp EAX, 0 jz iftrue cmp EAX, 1 jz iftrue cmp EAX, 3 jz iftrue ... jmp endif iftrue: ... endif:
-
switch
语句lea EBX, [case_values_table] xor EAX, EAX mov AL, case_index xlat mov ESI, EAX jmp [case_codeblocks_table][ESI * 4 or 8]
您只需要对每个选项的ASM指令的时序求和,包括由于清除操作码预取队列的正概率,任何jmp
s的潜在缺点。
但我相信,更好的建议是选择最受支持的C#代码
我不确定,但我希望switch语句是最快的,因为这里解释的原因,即通过作为哈希表的实现(对于超过5项的case语句),查找时间恒定。
为一个.Contains
创建一个新的int[]
似乎效率很低,但您可以使用常量字段来解决这个问题。此外,该方法必须在所有元素上迭代(最坏的情况),因此它可能是性能方面最不有利的选项。
if级联可能会击败开关if,因为在几乎所有情况下,第一个条件都是正确的,因为在确定之后它不必评估任何东西。
话虽如此,我通常会使用数组,因为它读起来很好,而且很容易更改。性能的提高通常是没有意义的。