C# List<T> vs IEnumerable<T> 性能问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1211491/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# List<T> vs IEnumerable<T> performance question
提问by PaN1C_Showt1Me
Hi suppose these 2 methods:
嗨,假设这两种方法:
private List<IObjectProvider> GetProviderForType(Type type)
{
List<IObjectProvider> returnValue = new List<IObjectProvider>();
foreach (KeyValuePair<Type, IObjectProvider> provider in _objectProviders)
{
if ((provider.Key.IsAssignableFrom(type) ||
type.IsAssignableFrom(provider.Key)) &&
provider.Value.SupportsType(type))
{
returnValue.Add(provider.Value);
}
}
return returnValue;
}
private IEnumerable<IObjectProvider> GetProviderForType1(Type type)
{
foreach (KeyValuePair<Type, IObjectProvider> provider in _objectProviders)
if ((provider.Key.IsAssignableFrom(type) ||
type.IsAssignableFrom(provider.Key)) &&
provider.Value.SupportsType(type))
yield return provider.Value;
}
Which one is quicker? When I look at the first method, I see that the memory is allocated for List, what in my opinion it's not needed. The IEnumerablemethod seems to be quicker to me.
哪个更快?当我查看第一种方法时,我看到为 List 分配了内存,我认为它不需要。该IEnumerable的方法似乎要快给我。
For instance, suppose you call
例如,假设你打电话
int a = GetProviderForType(myType).Count;
int b = GetProviderForType1(myType).Count();
Now, another issue is, is there a performance difference between these 2 above?
现在,另一个问题是,上面这两个之间是否存在性能差异?
What do you think?
你怎么认为?
采纳答案by Jon Skeet
In this particular case, using the IEnumerable<T>
form will be more efficient, because you onlyneed to know the count. There's no point in storing the data, resizing buffers etc if you don't need to.
在这种特殊情况下,使用IEnumerable<T>
表单会更有效率,因为您只需要知道计数。如果不需要,则存储数据、调整缓冲区大小等毫无意义。
If you needed to use the results again for any reason, the List<T>
form would be more efficient.
如果您出于任何原因需要再次使用结果,则List<T>
表单会更有效。
Note that both the Count()
extension method and the Count
property will be efficient for List<T>
as the implementation of Count()
checks to see if the target sequence implements ICollection<T>
and uses the Count
property if so.
请注意,Count()
扩展方法和Count
属性对于检查目标序列是否实现并使用属性(如果List<T>
是)的实现都是有效的。Count()
ICollection<T>
Count
Another option which should be even moreefficient (though only just) would be to call the overload of Count
which takes a delegate:
另一个应该更有效(虽然只是)的选择是调用它的重载,Count
它需要一个委托:
private int GetProviderCount(Type type)
{
return _objectProviders.Count(provider =>
(provider.Key.IsAssignableFrom(type)
|| type.IsAssignableFrom(provider.Key))
&& provider.Value.SupportsType(type));
}
That will avoid the extra level of indirections incurred by the Where
and Select
clauses.
这将避免由Where
andSelect
子句引起的额外的间接级别。
(As Marc says, for small amounts of data the performance differences will probably be negligible anyway.)
(正如 Marc 所说,对于少量数据,性能差异无论如何可能可以忽略不计。)
回答by Daniel Earwicker
The precise answer to questions like this can vary depending on a lot of factors, and may change further as the CLR evolves. The only way to be sure is to measure it - and bear in mind that if the difference is small compared to the operation this will appear in, then you should pick the most readable, maintainable way of writing it.
此类问题的准确答案可能因许多因素而异,并且可能会随着 CLR 的发展而进一步变化。唯一确定的方法是测量它 - 并记住,如果与将出现的操作相比差异很小,那么您应该选择最易读、最易维护的编写方式。
And on that note, you might also want to try:
关于这一点,您可能还想尝试:
private IEnumerable<IObjectProvider> GetProviderForType1(Type type)
{
return _objectProviders.Where(provider =>
provider.Key.IsAssignableFrom(type) ||
type.IsAssignableFrom(provider.Key)) &&
provider.Value.SupportsType(type))
.Select(p => p.Value);
}
You can also give yourself a lot of flexibility by returning IEnumerable<T>
and then using the ToList
extension method if you want to "snapshot" the results into a list. This will avoid repeated evaluation of the code to generate the list, if you need to examine it multiple times.
如果您想将结果“快照”到列表中,您还可以通过返回IEnumerable<T>
然后使用ToList
扩展方法来给自己很大的灵活性。如果您需要多次检查代码,这将避免重复评估代码以生成列表。
回答by Marc Gravell
An important part of this question is "how big is the data"? How many rows...
这个问题的一个重要部分是“数据有多大”?多少行...
For small amounts of data, list is fine - it will take negligible time to allocate a big enough list, and it won't resize many times (none, if you can tell it how big to be in advance).
对于少量数据,列表很好 - 分配足够大的列表所需的时间可以忽略不计,并且不会多次调整大小(没有,如果你能提前告诉它有多大)。
However, this doesn't scale to huge data volumes; it seems unlikely that your provider supports thousands of interfaces, so I wouldn't say it is necessaryto go to this model - but it won't hurt hugely.
然而,这并不能扩展到庞大的数据量;您的提供者似乎不太可能支持数以千计的接口,所以我不会说有必要采用这种模式 - 但它不会造成太大伤害。
Of course, you can use LINQ, too:
当然,您也可以使用 LINQ:
return from provider in _objectProviders
where provider.Key.IsAssignableFrom(type) ...
select provider.Value;
This is also the deferred yield
approach under the covers...
这也是yield
掩饰下的延迟方法......
回答by Vishal Patwardhan
The Main Difference Between IEnumerable and IList:
IEnumerable 和 IList 的主要区别:
IEnumerable: Implements MoveNext,Reset,Get Current Methods and Returns a Type of IEnumerator to Iterate Through Records.
IEnumerable:实现 MoveNext、Reset、Get Current 方法并返回一个 IEnumerator 类型以遍历记录。
IList : Exposes the IEnumerable Interface as well as it is also a collection of non-generic objects which can accessed through index so IEnumerable+ICollection(Manipulation of data) and add,remove,Insert(at specific Index) are the useful methods implemented by IList.
IList :公开 IEnumerable 接口以及它也是可以通过索引访问的非泛型对象的集合,因此 IEnumerable+ICollection(数据操作)和添加、删除、插入(在特定索引处)是由实现的有用方法列表。
After looking at your Code In My Opinion IEnumerable is more efficient but returning list is also useful if you want to do some manipulation with data and if you just want to Iterate through data then IEnumerable is preferable.
在我的意见中查看您的代码后,IEnumerable 更有效,但如果您想对数据进行一些操作,并且如果您只想遍历数据,则返回列表也很有用,那么 IEnumerable 更可取。