views:

157

answers:

1

Hello,

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().

+3  A: 

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

Andrew Barber
Interesting. What is the reasoning behind this difference?
Thilo
I really don't know offhand; in fact, it seemed so unlikely they would be different, I almost didn't check to see what methods they used to test equality.
Andrew Barber
Wouldn't you expect `IEquatable` to be faster though? Also a difference of x4 seems quite a lot.
Kobi
@Kobi ; those are my initial thoughts, too. My mind is too foggy to dig too much more tonight, though. hehe
Andrew Barber
Sorry, but no: `List<T>` also uses `EqualityComparer<T>` - which *provides* support for `IEquatable<T>`.
Marc Gravell
I worded that a bit inartfully; my point being that there is a slight difference in how the comparison is arrived at.
Andrew Barber
The comparison is the same (except or some indirection), except for the null-check (which I have profiled, and isn't the cause)
Marc Gravell