Performance impact of changing to generic interfac

2019-04-28 11:32发布

I work on applications developed in C#/.NET with Visual Studio. Very often ReSharper, in the prototypes of my methods, advises me to replace the type of my input parameters with more generic ones. For instance, List<> with IEnumerable<> if I only use the list with a foreach in the body of my method. I can understand why it looks smarter to write that but I'm quite concerned with the performance. I fear that the performance of my apps will decrease if I listen to ReSharper...

Can someone explain to me precisely (more or less) what's happening behind the scenes (i.e. in the CLR) when I write:

public void myMethod(IEnumerable<string> list)
{
  foreach (string s in list)
  {
    Console.WriteLine(s);
  }
}

static void Main()
{
  List<string> list = new List<string>(new string[] {"a", "b", "c"});
  myMethod(list);
}

and what is the difference with:

public void myMethod(List<string> list)
{
  foreach (string s in list)
  {
    Console.WriteLine(s);
  }
}

static void Main()
{
  List<string> list = new List<string>(new string[] {"a", "b", "c"});
  myMethod(list);
}

10条回答
对你真心纯属浪费
2楼-- · 2019-04-28 11:39

In the first version (IEnumerable) it is more generic and actually you say the method accepts any argument that implements this interface.

Second version yo restrict the method to accept sepcific class type and this is not recommended at all. And the performance is mostly the same.

查看更多
神经病院院长
3楼-- · 2019-04-28 11:41

The definition for List<T> is:

[SerializableAttribute]
public class List<T> : IList<T>, ICollection<T>, 
    IEnumerable<T>, IList, ICollection, IEnumerable

So List<T> is derived from IList, ICollection, IList<T>, and ICollection<T>, in addition to IEnumerable and IEnumerable<T>.

The IEnumerable interface exposes the GetEnumerator method which returns an IEnumerator, a MoveNext method, and a Current property. These mechanisms are what the List<T> class uses to iterate through the list with foreach and next.

It follows that, if IList, ICollection, IList<T>, and ICollection<T> are not required to do the job, then it's sensible to use IEnumerable or IEnumerable<T> instead, thereby eliminating the additional plumbing.

查看更多
该账号已被封号
4楼-- · 2019-04-28 11:43

There is no performance penalty for a static-upcast. It's a logical construct in program text.

As other people have said, premature optimization is the root of all evil. Write your code, run it through a hotspot analysis before you worry about performance tuning things.

查看更多
姐就是有狂的资本
5楼-- · 2019-04-28 11:43

In general, the increased flexibility will be worth what minor performance difference it would incur.

查看更多
Ridiculous、
6楼-- · 2019-04-28 11:48

An interface simply defines the presence and signature of public methods and properties implemented by the class. Since the interface does not "stand on its own", there should be no performance difference for the method itself, and any "casting" penalty - if any - should be almost too small to measure.

查看更多
何必那么认真
7楼-- · 2019-04-28 11:48

You'd have to look at the generated code to be certain, but in this case, I doubt there's much difference. The foreach statement always operates on an IEnumerable or IEnumerable<T>. Even if you specify List<T>, it will still have to get the IEnumerable<T> in order to iterate.

查看更多
登录 后发表回答