为什么 Any 比 contains 慢? [英] Why is Any slower than Contains?

查看:62
本文介绍了为什么 Any 比 contains 慢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我设计了以下测试:

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");

null 不存在时的结果:

The results when null is not present:

  • 包含假 00:00:00.0606484
  • Any == False 00:00:00.7532898
  • 任何对象.Equals False 00:00:00.8431783

当元素 4000 处存在 null 时:

When null is present at element 4000:

  • 包含真实的 00:00:00.0494515
  • Any == True 00:00:00.5929247
  • 任何对象.等于真 00:00:00.6700742

当元素 10 出现 null 时:

When null is present at element 10:

  • 包含真实的 00:00:00.0038035
  • Any == True 00:00:00.0025687
  • Any True 00:00:00.0033769

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

So when the object is near the front, Any is slightly faster; when it's at the back, it's much much slower. Why?

推荐答案

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

Any will have to call a delegate for every element it checks (an extra callvirt instruction which is unlikely to get inlined by the JIT). Contains only performs that check. That's why Any is slower. I suspect the fact that Any looks faster than contains when the element is seen very early is that the benchmark can't reflect it easily since they are very close. The setup time for the method call is the majority of the work done in that case (rather than the actual searching operation).

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 
...

这篇关于为什么 Any 比 contains 慢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆