更改为通用接口对性能的影响 [英] Performance impact of changing to generic interfaces

查看:113
本文介绍了更改为通用接口对性能的影响的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的工作用C#/。NET与Visual Studio应用程序。很多时候ReSharper的,在我的方法的原型,建议我用更通用的人取代我的输入参数的类型。例如,清单和LT;>用了IEnumerable<>如果我只用列表中我的方法的身体一个foreach。我可以理解为什么它看起来更加聪明,能写,但我很关心的性能。我担心我的应用程序的性能将会下降,如果我听ReSharper的...

能否有人向我解释precisely(或多或少),这是怎么回事幕后(即在CLR),当我写的:

 公共无效myMethod的(IEnumerable的<字符串>名单)
{
  的foreach(字符串s在名单)
  {
    Console.WriteLine(多个);
  }
}

静态无效的主要()
{
  名单<字符串>名单=新的名单,其中,串>(新的String [] {A,B,C});
  在myMethod(名单);
}
 

什么是区别:

 公共无效myMethod的(名单<字符串>名单)
{
  的foreach(字符串s在名单)
  {
    Console.WriteLine(多个);
  }
}

静态无效的主要()
{
  名单<字符串>名单=新的名单,其中,串>(新的String [] {A,B,C});
  在myMethod(名单);
}
 

解决方案

你担心性能 - 但是你有什么理由,这种担心?我的猜测是,你有没有在基准code在所有。 总是的更高性能code替换可读,干净code之前的基准。

在这种情况下,调用 Console.WriteLine 将彻底反正主宰性能。

虽然我怀疑有可能是一个的理论的使用之间的性能差异名单,其中,T> 的IEnumerable< T&GT ; 在这里,我怀疑病例数在那里的显著在现实世界中的应用程序是微乎其微

它甚至还不如,如果序列类型被用于许多运营 - 有以的GetEnumerator调用一次()被声明为返回 IEnumerator的< T> 反正。作为列表变大,在性能上两者之间有什么区别将变得更较小的,因为它只会造成任何影响都在循环的最开始。

但忽略了分析,东西取出来这是的测量的性能,你基本编码就可以了决定。之前

至于幕后发生的事情 - 你必须深入到究竟什么在每种情况下的元数据的深层细节。我怀疑,在接口的情况下,有重定向一个额外的层面,至少在理论上 - 在CLR将不得不在哪里工作在目标对象的类型的虚函数表的的IEnumerable< T> 是,然后调入相应的方法的code。在名单,其中的情况下,T> 的JIT会知道正确的偏移量虚表,开始时,没有额外的查找。这仅仅是基于对JITting,的thunk,虚函数表我有点朦胧认识,以及它们如何适用于接口。它可能是稍有不妥,但更重要的是它是一个实现细节。

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);
}

解决方案

You're worried about performance - but do you have any grounds for that concern? My guess is that you haven't benchmarked the code at all. Always benchmark before replacing readable, clean code with more performant code.

In this case the call to Console.WriteLine will utterly dominate the performance anyway.

While I suspect there may be a theoretical difference in performance between using List<T> and IEnumerable<T> here, I suspect the number of cases where it's significant in real world apps is vanishingly small.

It's not even as if the sequence type is being used for many operations - there's a single call to GetEnumerator() which is declared to return IEnumerator<T> anyway. As the list gets larger, any difference in performance between the two will get even smaller, because it will only have any impact at all at the very start of the loop.

Ignoring the analysis though, the thing to take out of this is to measure performance before you base coding decisions on it.

As for what happens behind the scenes - you'd have to dig into the deep details of exactly what's in the metadata in each case. I suspect that in the case of an interface there's one extra level of redirection, at least in theory - the CLR would have to work out where in the target object's type the vtable for IEnumerable<T> was, and then call into the appropriate method's code. In the case of List<T>, the JIT would know the right offset into the vtable to start with, without the extra lookup. This is just based on my somewhat hazy understanding of JITting, thunking, vtables and how they apply to interfaces. It may well be slightly wrong, but more importantly it's an implementation detail.

这篇关于更改为通用接口对性能的影响的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆