这是更快:单(谓语),或者(谓语)。单() [英] Which is faster: Single(predicate) or Where(predicate).Single()

查看:148
本文介绍了这是更快:单(谓语),或者(谓语)。单()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

期从导致这个答案有我好奇。这是更快:

  someEnumerable.Single(谓语); 

  someEnumerable.Where(谓语)。单(); 



毕竟,第一个是短,更简洁,似乎是特制的。



即使ReSharper的暗示前:





我是主张在以前的帖子,他们在功能上是相同的,并且应该有非常相似的运行时间。


解决方案

LINQ到对象



没有回答这样的问题这就像一个标杆:



(更新)

 类节目
{
const int的N = 10000;
挥发性私有静态诠释s_val;

静态无效DoTest(IEnumerable的< INT>的数据,INT []选择器){
秒表秒;

//使用。单(谓语)
S = Stopwatch.StartNew();
的foreach(在选择器变种T){
s_val = data.Single(X => X == T);
}
s.Stop();
Console.WriteLine({0}调用单(谓语)把{1}毫秒。,
selectors.Length,s.El​​apsedMilliseconds);

//使用。凡(谓语)。单()
S = Stopwatch.StartNew();
的foreach(在选择INT T){
s_val = data.Where(X => X == T)。单();
}
s.Stop();
Console.WriteLine({0}调用其中(谓语)。单()把{1}毫秒。,
selectors.Length,s.El​​apsedMilliseconds);
}


公共静态无效的主要(字串[] args){
变种R =新的随机();
变种选择= Enumerable.Range(0,N)。选择(_ => R.Next(0,N))ToArray的();

Console.WriteLine(使用IEnumerable的< INT>(Enumerable.Range()));
DoTest(Enumerable.Range(0,10 * N),选择器);

Console.WriteLine(使用INT []);
DoTest(Enumerable.Range(0,10 * N).ToArray(),选择器);

Console.WriteLine(使用列表< INT>中);
DoTest(Enumerable.Range(0,10 * N).ToList(),选择器);

Console.ReadKey();
}
}

有点令人震惊,。凡(谓语)。单()由约两倍的获胜。我甚至遇到这两种情况下的两倍,以确保高速缓存等并不是一个影响因素。



<预类=郎无prettyprint-覆盖> 1 )10000调用单(谓语)花了7938毫秒。
1)10000调用其中(谓语)。单()花了3795毫秒。
2)10000调用单(谓语)花了8132毫秒。
2)10000调用其中(谓语)。单()花了4318毫秒。

更新的结果:



<预类=郎无prettyprint-覆盖> 使用了IEnumerable< INT> (Enumerable.Range())
10000呼叫单(谓语)把7838毫秒。
10000呼叫凡(谓语)。单()花了8104毫秒。
使用INT []
10000呼叫单(谓语)花了8859毫秒。
10000呼叫凡(谓语)。单()花了2970毫秒。
使用列表< INT>
10000呼叫单(谓语)花了9523毫秒。
10000呼叫凡(谓语)。单()把3781毫秒。


Discussion resulting from this answer has me curious. Which is faster:

someEnumerable.Single(predicate);

or

someEnumerable.Where(predicate).Single();

After all, the first is shorter, more concise, and seems to be purpose-built.

Even ReSharper suggests the former:

I was arguing in the previous post, that they are functionally identical, and should have very similar runtime.

解决方案

LINQ-to-Objects

Nothing answers a question like this like a benchmark:

(Updated)

class Program
{
    const int N = 10000;
    volatile private static int s_val;

    static void DoTest(IEnumerable<int> data, int[] selectors) {
        Stopwatch s;

        // Using .Single(predicate)
        s = Stopwatch.StartNew();
        foreach (var t in selectors) {
            s_val = data.Single(x => x == t);
        }
        s.Stop();
        Console.WriteLine("   {0} calls to Single(predicate) took {1} ms.",
            selectors.Length, s.ElapsedMilliseconds);

        // Using .Where(predicate).Single()
        s = Stopwatch.StartNew();
        foreach (int t in selectors) {
            s_val = data.Where(x => x == t).Single();
        }
        s.Stop();
        Console.WriteLine("   {0} calls to Where(predicate).Single() took {1} ms.",
            selectors.Length, s.ElapsedMilliseconds);
    }


    public static void Main(string[] args) {
        var R = new Random();
        var selectors = Enumerable.Range(0, N).Select(_ => R.Next(0, N)).ToArray();

        Console.WriteLine("Using IEnumerable<int>  (Enumerable.Range())");
        DoTest(Enumerable.Range(0, 10 * N), selectors);

        Console.WriteLine("Using int[]");
        DoTest(Enumerable.Range(0, 10*N).ToArray(), selectors);

        Console.WriteLine("Using List<int>");
        DoTest(Enumerable.Range(0, 10 * N).ToList(), selectors);

        Console.ReadKey();
    }
}

Somewhat shockingly, .Where(predicate).Single() wins by a factor of about two. I even ran both cases twice to make sure caching, etc. was not a factor.

1) 10000 calls to Single(predicate) took 7938 ms.
1) 10000 calls to Where(predicate).Single() took 3795 ms.
2) 10000 calls to Single(predicate) took 8132 ms.
2) 10000 calls to Where(predicate).Single() took 4318 ms.

Updated Results:

Using IEnumerable<int>  (Enumerable.Range())
   10000 calls to Single(predicate) took 7838 ms.
   10000 calls to Where(predicate).Single() took 8104 ms.
Using int[]
   10000 calls to Single(predicate) took 8859 ms.
   10000 calls to Where(predicate).Single() took 2970 ms.
Using List<int>
   10000 calls to Single(predicate) took 9523 ms.
   10000 calls to Where(predicate).Single() took 3781 ms.

这篇关于这是更快:单(谓语),或者(谓语)。单()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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