【问题标题】:Generic method vs non generic method - is there any performance benefit?通用方法与非通用方法 - 是否有任何性能优势?
【发布时间】:2012-09-16 10:30:58
【问题描述】:

我正在用 C# 创建我的第一个网站。

我注意到我在智能感知中得到了一些重复的扩展方法。进一步调查是这两个:

public static void ThrowNullOrEmpty<T>(this IEnumerable<T> obj, string param)
{
}

public static void ThrowNullOrEmpty(this string obj, string param)
{
}

好像字符串也可以是IEnumerable&lt;char&gt;

从编译的基础上,我可以删除字符串变体,但是否有任何性能问题或其他我应该注意的问题?

更新

刚刚测试了超过 100 万次迭代。

public bool IsNullOrEmpty1(string @this)
{
    return String.IsNullOrEmpty(@this);
}

public bool IsNullOrEmpty2<T>(IEnumerable<T> @this)
{
    return @this == null || !@this.Any();
}

IsNullOrEmpty1 在我的开发机器 IsNullOrEmpty2 (125 - 250ms) 上运行 12 毫秒,因此慢了 10 - 20 倍。

在现实世界中,我计算了每月 3000 万次迭代的极高数字,这相当于每分钟 1388 次(每天 12 小时)。结果两者都不到 1 毫秒。

因此,删除 IsNullOrEmpty1 不是最好的方法,但也不是网站杀手。

【问题讨论】:

  • 据我所知,它是语法糖,编译器会为您的泛型生成一个新类型。在运行时,您应该不会注意到差异。
  • 这么容易衡量,但除非有问题,否则何必费心呢?

标签: c# .net generics extension-methods


【解决方案1】:

这可能取决于这些方法的实现——字符串版本可以针对性能进行优化,而IEnumerable&lt;T&gt; 需要更通用。调用泛型方法没有开销,它已经在编译时解析为正确的泛型参数。

字符串版本可以这样实现,开销很小(基本上需要做两次比较):

if (String.IsNullOrEmpty(value))  

另一方面,IEnumerable&lt;T&gt; 可能必须像这样实现:

if (value == null || !value.Any())

这里的关键是Any 调用,它将调用GetEnumerator 方法并返回一个枚举器。 (为简单起见,我们将忽略框架可能在内部对某些类型使用的性能优化,这里)。这意味着该实现实际上创建了一个新对象,稍后需要对它进行垃圾回收 - 两者都需要比进行string 版本中提到的两个比较更多的时钟周期。

在实践中,除非这些方法被非常频繁地调用,否则我怀疑会有任何显着的性能差异。

顺便说一句,这行得通的原因是stringIEnumerable&lt;char&gt;

【讨论】:

    【解决方案2】:

    string是一个密封类,所以我们可以直接调用string类中的方法,而不需要访问虚函数指针。 理论上,它比通过 IEnumerable&lt;char&gt; 更快。但实际上,这取决于您在方法中调用string 方法的次数。

    【讨论】:

      猜你喜欢
      • 2017-03-04
      • 2011-03-11
      • 1970-01-01
      • 1970-01-01
      • 2011-06-11
      • 2011-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多