有什么不同?
在集合上使用Linq,以下几行代码有什么不同?
if(!coll.Any(i => i.Value))
和
if(!coll.Exists(i => i.Value))
更新1
当我拆解。 .Exists
它看起来像没有代码。
更新2
任何人都知道为什么这里没有代码?
请参阅文档
List.Exists(对象方法 - MSDN)
确定List(T)是否包含与由指定的谓词定义的条件相匹配的元素。
这是从.NET 2.0开始的,所以在LINQ之前。 意味着与Predicate 委托一起使用,但是lambda表达式是向后兼容的。 此外,只有List有这个(甚至没有IList)
IEnumerable.Any(扩展方法 - MSDN)
确定序列的任何元素是否满足条件。
这在.NET 3.5中是新的,并且使用Func(TSource,bool)作为参数,所以这是为了与lambda表达式和LINQ一起使用。
在行为中,这些是相同的。
区别在于Any是System.Linq.Enumerable上定义的任何IEnumerable<T>
的扩展方法。 它可以用于任何IEnumerable<T>
实例。
存在似乎不是一种扩展方法。 我的猜测是coll是List<T>
类型。 如果是这样的话Exists是一个与Any非常相似的实例方法。
总之 ,这些方法基本上是相同的。 一个比另一个更普遍。
TLDR; 性能方面Any
似乎都比较慢 (如果我已经正确设置了这个值,几乎同时评估两个值)
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;
}
拥有10M记录
“任何:00:00:00.3770377存在:00:00:00.2490249”
有5M记录
“任何时间:00:00:00.0940094 Exists:00:00:00.1420142”
拥有1M记录
“任何:00:00:00.0180018存在:00:00:00.0090009”
有了500k,(我也翻过了评估的顺序,看看是否没有其他操作与先运行相关。)
“Exists:00:00:00.0050005 Any:00:00:00.0100010”
拥有10万条记录
“Exists:00:00:00.0010001 Any:00:00:00.0020002”
看起来Any
情况都会减慢2。
编辑:对于5和10M记录,我改变了它生成列表的方式, Exists
突然变得比Any
更慢,这意味着我正在测试的方式有问题。
新的测试机制:
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"))
{
}
}
编辑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"))
{
}
}
}
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”
链接地址: http://www.djcxy.com/p/52941.html