I have List which has 150K elements. Average time of work IndexOf() is 4 times lower than Contains(). I tried to use List of int. For List of strings IndexOf is a bit faster.
I found only one main difference, it's attribute TargetedPatchingOptOut. MSDN tells:
Indicates that the .NET Framework class library method to which this attribute is applied is unlikely to be affected by servicing releases, and therefore is eligible to be inlined across Native Image Generator (NGen) images.
Could this attribute be a reason of such behavior? And why doesn't method Contains() have such attribute?
Thanks in advance.
EDIT:
I have code something like this:
List<int> list = CommonHelper.GetRandomList(size);
long min = long.MaxValue;
long max = 0;
long sum = 0;
foreach (var i in list)
{
m_stopwatch.Reset();
m_stopwatch.Start();
list.Contains(i); // list.IndexOf(i);
m_stopwatch.Stop();
long ticks = m_stopwatch.ElapsedTicks;
if (ticks < min)
min = ticks;
if (ticks > max)
max = ticks;
sum += ticks;
}
long averageSum = sum / size;
EDIT 2:
I have written same code as in IndexOf() and it work slower than Contains().
IndexOf(string) has no options and Contains() uses an Ordinal compare (a byte-by-byte comparison rather than trying to perform a smart compare, for example, e with é). So IndexOf will be marginally faster (in theory) as IndexOf goes straight to a string search using FindNLSString from kernel32.
Contains() is about the same speed as, or slightly faster than, the loop. Here's my test code. To test this code, you should compile it as an x86 RELEASE build, and run it from outside the debugger. As you can see, the loop takes around 1/3 the time on my system.
Contains() ought to be around 50 nanoseconds. So the overall operation takes 50.05 microseconds. A faster Contains might take half the time, the overall operation takes 50.025 microseconds.
List size can be increased up to 2 billion (only when your system works on 64-bit or higher) to store large List<T> objects.
They each arrive at the method to determine equality slightly differently, according to their MSDN entries. Look under the 'remarks' of each of these entries:
List<T>.IndexOf
uses EqualityComparer<T>.Default
http://msdn.microsoft.com/en-us/library/e4w08k17.aspx
List<T>.Contains
uses IEquatable<T>.Equals
http://msdn.microsoft.com/en-us/library/bhkz42b3.aspx
Even if they end up calling the same method to determine equality in the very end (as is certainly the case here), they are taking different routes to get there, so that probably 'splains it.
Given that the "4x difference" seems not to be the actual case, some off-handed boxing might account for some difference, particularly with a 150k sized set of data
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With