var list1 = Generate(1000000);
var forceListEval = list1.SingleOrDefault(o => o == "0123456789012");
if (forceListEval != "sdsdf")
{
var s = string.Empty;
var start2 = DateTime.Now;
if (!list1.Exists(o => o == "0123456789012"))
{
var end2 = DateTime.Now;
s += " Exists: " + end2.Subtract(start2);
}
var start1 = DateTime.Now;
if (!list1.Any(o => o == "0123456789012"))
{
var end1 = DateTime.Now;
s +=" Any: " +end1.Subtract(start1);
}
if (!s.Contains("sdfsd"))
{
}
测试列表生成器:
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;
}
private static IEnumerable<string> Generate(int count)
{
var cripto = new RNGCryptoServiceProvider();
Func<string> getString = () => new string(
Enumerable.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 13)
.Select(s =>
{
var cryptoResult = new byte[4];
cripto.GetBytes(cryptoResult);
return s[new Random(BitConverter.ToInt32(cryptoResult, 0)).Next(s.Length)];
})
.ToArray());
var list = new ConcurrentBag<string>();
var x = Parallel.For(0, count, o => list.Add(getString()));
return list;
}
private static void Test()
{
var list = Generate(10000000);
var list1 = list.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"))
{
}
}
**Edit 2:**好的,为了消除生成测试数据的任何影响,我将其全部写入文件,现在从那里读取它。
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"))
{
}
}
}
6条答案
按热度按时间yhxst69z1#
参阅文档
List.Exists(对象方法- MSDN)
确定List(T)是否包含与指定 predicate 定义的条件匹配的元素。
这是从.NET 2.0开始的,所以在LINQ之前。本应与Predicatedelegate一起使用,但lambda表达式是向后兼容的。此外,只有List才有这个(甚至IList也没有)
IEnumerable.Any(扩展方法- MSDN)
确定序列的任何元素是否满足条件。
这在.NET 3.5中是新的,使用Func(TSource,bool)作为参数,因此它旨在与lambda表达式和LINQ一起使用。
在行为上,它们是相同的。
qzwqbdag2#
不同之处在于,
Any
是extension method
,适用于在System.Linq.Enumerable
上定义的任何IEnumerable<T>
。它可以在任何IEnumerable<T>
示例上使用。Exists
似乎不是extension method
。我猜科尔的类型是List<T>
。如果是这样的话,Exists
是一个instance method
,它的功能与Any
非常相似。*Any也有一个重载,它不带参数,只是在可查询对象中查找任何项。
*Exists没有这样的重载。
6fe3ivhb3#
TLDR; 性能方面的
Any
似乎更慢*(如果我正确设置了它,几乎同时评估两个值)测试列表生成器:
10 M记录
“任何:00:00:00.3770377存在:00:00:00.2490249”
500万条记录
“任何:00:00:00.0940094评论者:00:00:00.1420142”
1 M记录
“任何:00:00:00.0180018存在:00:00:00.0090009”
对于500 k,(我还翻转了它们被评估的顺序,以查看是否没有与首先运行的操作相关联的额外操作。
“存在:00:00:00.0050005任意:00:00:00.0100010”
10万条记录
“存在:00:00:00.0010001任意:00:00:00.0020002”
看起来
Any
慢了2个数量级。**编辑:**对于5 M和10 M的记录,我改变了它生成列表的方式,
Exists
突然变得比Any
慢,这意味着我的测试方式有问题。新的测试机制:
**Edit 2:**好的,为了消除生成测试数据的任何影响,我将其全部写入文件,现在从那里读取它。
10M
“任何:00:00:00.1640164存在:00:00:00.0750075”
5M
“任何:00:00:00.0810081存在:00:00:00.0360036”
1M
“任何:00:00:00.0190019存在:00:00:00.0070007”
500k
“任何:00:00:00.0120012存在:00:00:00.0040004”
xoefb8l84#
作为对Matas关于基准测试的回答的延续。
TL/DR:Exists()和Any()同样快。
首先:使用秒表进行基准测试并不精确(see series0ne's answer on a different, but similiar, topic),但它比DateTime精确得多。
获得真正精确读数的方法是使用性能分析。但是,了解这两个方法的性能如何相互衡量的一种方法是执行两个方法 * 加载 * 次,然后比较每个方法的最快执行时间。这样,JIT和其他噪声给我们带来的读数不好(确实如此)真的不重要,因为在某种意义上,这两种执行都是“同样误导”。
在执行上述代码4次之后(依次在一个有1000000个元素的列表上执行1000
Exists()
和Any()
),不难看出这些方法几乎同样快。有一个微小的差异,但它太小了,不能用背景噪音来解释。我的猜测是,如果一个人做10 000或100 000
Exists()
和Any()
,那么这个微小的差异或多或少会消失。yrwegjxp5#
当您校正测量值时-如上所述:Any和Exists,并添加平均值-我们将得到以下输出:
cigdeys36#
此外,只有当Value的类型为bool时,这才有效。通常,这与 predicate 一起使用。任何 predicate 通常用来判断是否存在满足给定条件的元素.在这里,您只是将元素iMap到bool属性。它将搜索Value属性为true的“i”。一旦完成,该方法将返回true。