为什么比包含更慢?

Mas*_*low 8 c# performance

我设计了以下测试:

var arrayLength=5000;
object[] objArray=new object[arrayLength];

for(var x=0;x<arrayLength;x++)
{
    objArray[x]=new object();
}
objArray[4000]=null;
const int TestSize=int.MaxValue;

System.Diagnostics.Stopwatch v= new Stopwatch();
v.Start();
for(var x=0;x<10000;x++)
{
    objArray.Contains(null);
}
v.Stop();
objArray.Contains(null).Dump();
v.Elapsed.ToString().Dump("Contains");

//Any ==
v.Reset();
v.Start();
for(var x=0;x<10000;x++)
{
    objArray.Any(o=>o==null);
}
v.Stop();
objArray.Any(x=>x==null).Dump();
v.Elapsed.ToString().Dump("Any");

//Any Equals
v.Reset();
v.Start();
for(var x=0;x<10000;x++)
{
    objArray.Any(obj=>object.Equals( obj,null));
}
v.Stop();
objArray.Any(obj=>object.Equals( obj,null)).Dump();
v.Elapsed.ToString().Dump("Any");
Run Code Online (Sandbox Code Playgroud)

null不存在时的结果:

  • Contains False 00:00:00.0606484
  • Any == False 00:00:00.7532898
  • Any object.Equals False 00:00:00.8431783

当元素4000存在null时:

  • Contains True 00:00:00.0494515
  • Any == True 00:00:00.5929247
  • Any object.Equals True 00:00:00.6700742

当元素10出现null时:

  • Contains True 00:00:00.0038035
  • Any == True 00:00:00.0025687
  • Any True 00:00:00.0033769

所以当物体靠近前方时,Any会稍快一点; 当它在后面时,速度要慢得多.为什么?

Meh*_*ari 8

Any将不得不为它检查的每个元素调用一个委托(一个callvirt不太可能被JIT内联的额外指令).Contains只执行该检查.这就是为什么Any慢一点.我怀疑Any看起来比包含元素的时候看起来更快的事实是基准测试不能很容易地反映它,因为它们非常接近.方法调用的设置时间是在这种情况下完成的大部分工作(而不是实际的搜索操作).

The anonymous method:
--- C:\Users\Mehrdad\AppData\Local\Temporary Projects\ConsoleApplication1\Program.cs 
            Console.WriteLine(s.Any(a => a == 1));
00000000  xor         eax,eax 
00000002  cmp         ecx,1 
00000005  sete        al 
00000008  ret 

Relevant part of Enumerable.Any code:
...
00000051  mov         edx,eax 
00000053  mov         rcx,qword ptr [rbx+8] 
00000057  call        qword ptr [rbx+18h]   // calls the anonymous method above
0000005a  movzx       ecx,al 
0000005d  test        ecx,ecx 
...
Run Code Online (Sandbox Code Playgroud)

  • @Paul,我觉得你不需要我这个.除了当然要指出所有这些猜测都是*猜测* - 消息灵通,合理的猜测,但不过,猜测.如果你想知道花费的时间,*运行一个分析器*. (4认同)