TLDR; In Bezug auf die Leistung Any
scheint es langsamer zu sein (wenn ich dies richtig eingerichtet habe, um beide Werte fast gleichzeitig auszuwerten)
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"))
{
}
Testlistengenerator:
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;
}
Mit 10 Millionen Datensätzen
Any: 00: 00: 00.3770377 Exists: 00: 00: 00.2490249
Mit 5 Millionen Datensätzen
"Any: 00: 00: 00.0940094 Exists: 00: 00: 00.1420142"
Mit 1M Datensätzen
"Any: 00: 00: 00.0180018 Exists: 00: 00: 00.0090009"
Mit 500k (Ich habe auch die Reihenfolge umgedreht, in der sie ausgewertet werden, um festzustellen, ob keine zusätzliche Operation mit der zuerst ausgeführten Operation verbunden ist.)
"Exists: 00: 00: 00.0050005 Any: 00: 00: 00.0100010"
Mit 100.000 Datensätzen
"Exists: 00: 00: 00.0010001 Any: 00: 00: 00.0020002"
Es scheint Any
um die Größe 2 langsamer zu sein.
Bearbeiten: Bei 5 und 10 Millionen Datensätzen habe ich die Art und Weise geändert, in der die Liste erstellt wird, und bin Exists
plötzlich langsamer geworden, als Any
dies impliziert, dass beim Testen etwas nicht stimmt.
Neuer Testmechanismus:
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"))
{
}
}
Edit2: Ok, um jeglichen Einfluss von der Generierung von Testdaten auszuschließen, habe ich alles in eine Datei geschrieben und jetzt von dort gelesen.
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
"Any: 00: 00: 00.1640164 Exists: 00: 00: 00.0750075"
5M
"Beliebig: 00: 00: 00.0810081 Exists: 00: 00: 00.0360036"
1M
"Any: 00: 00: 00.0190019 Exists: 00: 00: 00.0070007"
500k
"Any: 00: 00: 00.0120012 Exists: 00: 00: 00.0040004"