Loop implementation of List.Contains() appears faster than the built-in one. Is it? If so, why?

后端 未结 2 1953
星月不相逢
星月不相逢 2021-01-11 12:01

(This question arises from a discussion that started here)

I was comparing the timings for looking for a true value in a List u

2条回答
  •  栀梦
    栀梦 (楼主)
    2021-01-11 13:02

    It uses GenericEqualityComparer, if we look at the implementation of the Equals method is looks like this:

    public override bool Equals(T x, T y)
    {
      if ((object) x != null)
      {
        if ((object) y != null)
          return x.Equals(y);
        else
          return false;
      }
      else
        return (object) y == null;
    }
    

    When it checks whether the objects are not equal to null, it makes boxing them and you get two boxing operation. This IL-code shows how it looks:

    IL_0002: box !T
    IL_0007: ldnull
    IL_0008: ceq
    

    Edit by 280Z28: The CIL for the same method is slightly different in .NET 4.5.

    public override bool Equals(T x, T y)
    {
        if (x != null)
            return ((y != null) && x.Equals(y));
    
        if (y != null)
            return false;
    
        return true;
    }
    

    Here is the IL. For anyone looking at Reflector, note that brfalse.s and brnull.s are the same instruction.

    L_0000: ldarg.1 
    L_0001: box !T
    L_0006: brnull.s L_0021
    ...
    

    The baseline JIT compiler does not optimize away the box operation, but I have not checked with NGen or the optimizing compiler to see if they do.

提交回复
热议问题