Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ.任何VS.存在-什么';有什么区别?_C#_Linq_Collections - Fatal编程技术网

C# LINQ.任何VS.存在-什么';有什么区别?

C# LINQ.任何VS.存在-什么';有什么区别?,c#,linq,collections,C#,Linq,Collections,在集合上使用LINQ,以下代码行之间的区别是什么 if(!coll.Any(i => i.Value)) 及 更新1 当我反汇编.Exists时,看起来好像没有代码 更新2 有人知道为什么这里没有这个的代码吗?区别在于Any是System.Linq.Enumerable上定义的AnyIEnumerable的扩展方法。它可以用于任何IEnumerable实例 Exists似乎不是扩展方法。我的猜测是coll属于List类型。如果存在,则是一个实例方法,其功能与任何实例方法非常相似 简而言之

在集合上使用LINQ,以下代码行之间的区别是什么

if(!coll.Any(i => i.Value))

更新1

当我反汇编
.Exists
时,看起来好像没有代码

更新2


有人知道为什么这里没有这个的代码吗?

区别在于Any是System.Linq.Enumerable上定义的Any
IEnumerable
的扩展方法。它可以用于任何
IEnumerable
实例

Exists似乎不是扩展方法。我的猜测是coll属于
List
类型。如果存在,则是一个实例方法,其功能与任何实例方法非常相似

简而言之,方法基本相同。一个比另一个更一般

  • Any还有一个重载,它不接受任何参数,只查找可枚举项中的任何项
  • 存在没有此类重载

此外,仅当值为bool类型时,此选项才有效。这通常与谓词一起使用。任何谓词通常用于查找是否有任何元素满足给定条件。在这里,你只是在做一个从元素i到bool属性的映射。它将搜索值属性为true的“i”。完成后,该方法将返回true。

请参阅文档

(对象方法-MSDN)

确定列表(T)是否包含与指定谓词定义的条件匹配的元素

这是自.NET2.0以来就存在的,所以在LINQ之前。表示与谓词委托一起使用,但lambda表达式向后兼容。而且,just List有这样的功能(甚至不包括IList)

(扩展方法-MSDN)

确定序列的任何元素是否满足条件

这在.NET3.5中是新的,它使用Func(TSource,bool)作为参数,因此它打算与lambda表达式和LINQ一起使用


在行为上,它们是相同的。

TLDR性能方面的
任何
似乎都比较慢(如果我已正确设置此选项,以便几乎同时计算这两个值)

测试列表生成器:

private List<string> Generate(int count)
    {
        var list = new List<string>();
        for (int i = 0; i < count; i++)
        {
            list.Add( new string(
            Enumerable.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 13)
                .Select(s =>
                {
                    var cryptoResult = new byte[4];
                    new RNGCryptoServiceProvider().GetBytes(cryptoResult);
                    return s[new Random(BitConverter.ToInt32(cryptoResult, 0)).Next(s.Length)];
                })
                .ToArray())); 
        }

        return list;
    }
Edit2:好的,为了消除生成测试数据的任何影响,我将其全部写入文件,现在从文件中读取

 private static void Test()
    {
        var list1 = File.ReadAllLines("test.txt").Take(500000).ToList();
        var forceListEval = list1.SingleOrDefault(o => o == "0123456789012");
        if (forceListEval != "sdsdf")
        {
            var s = string.Empty;
            var start1 = DateTime.Now;
            if (!list1.Any(o => o == "0123456789012"))
            {
                var end1 = DateTime.Now;
                s += " Any: " + end1.Subtract(start1);
            }

            var start2 = DateTime.Now;
            if (!list1.Exists(o => o == "0123456789012"))
            {
                var end2 = DateTime.Now;
                s += " Exists: " + end2.Subtract(start2);
            }

            if (!s.Contains("sdfsd"))
            {
            }
        }
    }
10米

“任何:00:00:00.1640164存在:00:00:00.0750075”

5米

“任何:00:00:00.0810081存在:00:00:00.0360036”

1米

“任何:00:00:00.0190019存在:00:00:00.0070007”

500k

“任何:00:00:00.0120012存在:00:00:00.0040004”

作为基准测试的延续

TL/DR:Exists()和Any()速度相同

Fastest Exists() execution: 57881 ticks
Fastest Any() execution: 58272 ticks

Fastest Exists() execution: 58133 ticks
Fastest Any() execution: 58063 ticks

Fastest Exists() execution: 58482 ticks
Fastest Any() execution: 58982 ticks

Fastest Exists() execution: 57121 ticks
Fastest Any() execution: 57317 ticks
首先:使用秒表进行基准测试并不精确(),但它比DateTime精确得多

获得真正精确读数的方法是使用性能分析。但要了解这两种方法的性能如何相互衡量,一种方法是执行这两种方法的加载次数,然后比较每种方法的最快执行时间。这样,JITing和其他噪音给我们的读数不好其实并不重要(确实如此),因为这两种执行在某种意义上都是“同样的误导”

static void Main(string[] args)
    {
        Console.WriteLine("Generating list...");
        List<string> list = GenerateTestList(1000000);
        var s = string.Empty;

        Stopwatch sw;
        Stopwatch sw2;
        List<long> existsTimes = new List<long>();
        List<long> anyTimes = new List<long>();

        Console.WriteLine("Executing...");
        for (int j = 0; j < 1000; j++)
        {
            sw = Stopwatch.StartNew();
            if (!list.Exists(o => o == "0123456789012"))
            {
                sw.Stop();
                existsTimes.Add(sw.ElapsedTicks);
            }
        }

        for (int j = 0; j < 1000; j++)
        {
            sw2 = Stopwatch.StartNew();
            if (!list.Exists(o => o == "0123456789012"))
            {
                sw2.Stop();
                anyTimes.Add(sw2.ElapsedTicks);
            }
        }

        long existsFastest = existsTimes.Min();
        long anyFastest = anyTimes.Min();

        Console.WriteLine(string.Format("Fastest Exists() execution: {0} ticks\nFastest Any() execution: {1} ticks", existsFastest.ToString(), anyFastest.ToString()));
        Console.WriteLine("Benchmark finished. Press any key.");
        Console.ReadKey();
    }

    public static List<string> GenerateTestList(int count)
    {
        var list = new List<string>();
        for (int i = 0; i < count; i++)
        {
            Random r = new Random();
            int it = r.Next(0, 100);
            list.Add(new string('s', it));
        }
        return list;
    }

有一点差别,但差别太小,不能用背景噪音来解释。我的猜测是,如果一个人做10000或100000个
Exists()
Any()
取而代之,这个微小的差异将或多或少消失。

当你纠正测量值时——如上所述:Any和Exists,并加上平均值——我们将得到以下输出:

Executing search Exists() 1000 times ... 
Average Exists(): 35566,023
Fastest Exists() execution: 32226 

Executing search Any() 1000 times ... 
Average Any(): 58852,435
Fastest Any() execution: 52269 ticks

Benchmark finished. Press any key.

说得好(+1)。Exists自.NET2以来一直存在,但仅适用于一般列表。在.NET3中添加了IEnumerable.Any,作为可用于任何可枚举集合的扩展。还有类似的成员,比如List.Count,它是一个属性,IEnumerable.Count()-一个方法。您编译的代码是什么样子的?你是怎么拆开的?伊尔达斯姆?您希望找到什么但没有找到?我后来列出了.NET2
List
实例方法的所有Linq“等价物”。这里的一些答案说any()比exists()慢。但在现实世界的用例中,您通常可以将其与其他Linq方法结合使用,这将使其更快,例如
myIEnum.Where(a=>String.Equals(a.sex,“male”)).Any(a=>String.Equals(a.name,“Joe”)
。你不能像这样使用where()和exists()。这对你来说没有什么不好,但我对这些基准表示怀疑。看看数字:每个结果都有一个递归发生(3770377:2490249)。至少对我来说,这是一个肯定的迹象,有些事情是不正确的。我对这里的数学不是百分之百的肯定,但我认为这种重复模式发生的几率是每一个值999^999(或者999!也许?)中的1。所以它连续发生8次的几率是微乎其微的。我想这是因为你使用了。@JerriKangasniemi在隔离状态下重复相同的操作应该总是需要相同的时间,重复多次也需要相同的时间。你为什么说这是约会时间?当然了。问题仍然是,对于500k的呼叫,要花0120012秒的时间是非常不可能的。如果它是完全线性的,从而很好地解释了这些数字,那么一百万次呼叫将花费0240024秒(两倍长),但事实并非如此。1M通话比500k长58%(3%),10M通话比5M长102.5%。所以它不是一个线性函数,因此,所有的数字都递归是不合理的。我提到DateTime是因为我自己在过去也遇到过问题,因为DateTime没有使用高精度计时器。@JerriKangasniemi我可以建议你修复它并发布一个答案吗?如果我正确阅读了你的结果,你报告的任何结果的速度仅为现有速度的2到3倍。我
static void Main(string[] args)
    {
        Console.WriteLine("Generating list...");
        List<string> list = GenerateTestList(1000000);
        var s = string.Empty;

        Stopwatch sw;
        Stopwatch sw2;
        List<long> existsTimes = new List<long>();
        List<long> anyTimes = new List<long>();

        Console.WriteLine("Executing...");
        for (int j = 0; j < 1000; j++)
        {
            sw = Stopwatch.StartNew();
            if (!list.Exists(o => o == "0123456789012"))
            {
                sw.Stop();
                existsTimes.Add(sw.ElapsedTicks);
            }
        }

        for (int j = 0; j < 1000; j++)
        {
            sw2 = Stopwatch.StartNew();
            if (!list.Exists(o => o == "0123456789012"))
            {
                sw2.Stop();
                anyTimes.Add(sw2.ElapsedTicks);
            }
        }

        long existsFastest = existsTimes.Min();
        long anyFastest = anyTimes.Min();

        Console.WriteLine(string.Format("Fastest Exists() execution: {0} ticks\nFastest Any() execution: {1} ticks", existsFastest.ToString(), anyFastest.ToString()));
        Console.WriteLine("Benchmark finished. Press any key.");
        Console.ReadKey();
    }

    public static List<string> GenerateTestList(int count)
    {
        var list = new List<string>();
        for (int i = 0; i < count; i++)
        {
            Random r = new Random();
            int it = r.Next(0, 100);
            list.Add(new string('s', it));
        }
        return list;
    }
Fastest Exists() execution: 57881 ticks
Fastest Any() execution: 58272 ticks

Fastest Exists() execution: 58133 ticks
Fastest Any() execution: 58063 ticks

Fastest Exists() execution: 58482 ticks
Fastest Any() execution: 58982 ticks

Fastest Exists() execution: 57121 ticks
Fastest Any() execution: 57317 ticks
Executing search Exists() 1000 times ... 
Average Exists(): 35566,023
Fastest Exists() execution: 32226 

Executing search Any() 1000 times ... 
Average Any(): 58852,435
Fastest Any() execution: 52269 ticks

Benchmark finished. Press any key.