通用方法与非通用方法 - 是否有任何性能优势?

时间:2012-09-16 10:30:58

标签: c# .net generics extension-methods

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

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

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

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

似乎字符串也可以是IEnumerable<char>

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

更新

刚刚测试超过1米的迭代次数。

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

VS

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

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

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

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

2 个答案:

答案 0 :(得分:3)

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

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

if (String.IsNullOrEmpty(value))  

另一方面,IEnumerable<T>可能必须实现如下:

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

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

在实践中,除非经常调用这些方法,否则我怀疑是否存在任何显着的性能差异。

顺便说一下,其原因在于stringIEnumerable<char>

答案 1 :(得分:0)

string是一个密封类,因此我们可以直接调用string类中的方法而无需访问虚函数指针。 从理论上讲,它比传递I Enumerable<char>更快。但实际上,这取决于您在方法中调用string方法的次数。