Array#Contain vs OR逻辑与switch语句的性能

时间:2014-04-24 07:45:12

标签: c#

哪一个最快,哪个最慢(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;
}

2 个答案:

答案 0 :(得分:1)

这些东西的性能取决于目标机器架构和操作系统 对于x86 / x64机器,我认为上面的代码应该由JIT翻译成以下汇编程序:

  1. Array.Contains方法

    lea    EDI, [...]
    mov    ECX, sizeof(...)
    repne  scasd
    
  2. OR声明中的序列if

    mov    EAX, ...
    cmp    EAX, 0
    jz     iftrue
    cmp    EAX, 1
    jz     iftrue
    cmp    EAX, 3
    jz     iftrue
    ...
    jmp    endif
    iftrue:
    ...
    endif:
    
  3. 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]
    
  4. 您唯一需要的是对每个选项的ASM指令的时序进行求和,包括由于清除操作码预取队列的正概率,任何jmp潜在缺点。

    但我相信,更好的建议是选择最可支持的C#代码。

答案 1 :(得分:-2)

我不确定,但我希望switch语句最快,因为here解释的原因,即通过实现作为哈希表的常量查找时间(对于超过5项的case语句) ,就是)。

为一个int[]创建新的.Contains似乎非常低效,但您可以使用常量字段来解决这个问题。此外,该方法必须迭代所有元素(最坏情况),因此它可能是最不利的选项性能明智

如果第一个条件是正确的,那么if cascade可能会击败switch if ,因为在确定之后它不需要评估任何内容。

话虽这么说,我通常会使用数组,只是因为它读得很好而且很容易改变。性能提升通常没有实际意义。