tra*_*m_3 1 c# performance list
List<T>()in 的默认容量System.Collections.Generic为0.
说我有一个功能
private IEnumerable<SomeType> DoStuff(IEnumerable<OtherType> e)
{
var list = new List<SomeType>();
foreach (var elem in e)
{
list.Add(new SomeType
{
SomeProperty = elem.OtherProperty
});
}
return list;
}
Run Code Online (Sandbox Code Playgroud)
我list在运行循环之前设置了大小,如下所示:
private IEnumerable<SomeType> DoStuff(IEnumerable<OtherType> e)
{
var list = new List<SomeType>(e.Count());
foreach (var elem in e)
{
list.Add(new SomeType
{
SomeProperty = elem.OtherProperty
});
}
return list;
}
Run Code Online (Sandbox Code Playgroud)
它是否会影响运行时间,或者没有理由这样做,因为它的大小e是"动态的"?
这取决于IEnumerable<OtherType> e...... 的类型
e.Count()
Run Code Online (Sandbox Code Playgroud)
可以枚举ejust来计算它...如果e是对db的查询,它将被执行两次,一次用于e.Count()和一次用于foreach......慢!
如果e是一个List<>或一个OtherType[]或其他类型的实现ICollection<>然后Count()使用该Count属性,所以它不枚举IEnumerable<>.
请注意,对于这个简单的情况,您可以:
return e.Select(x => new SomeType { SomeProperty = x.OtherProperty })
.ToList();
Run Code Online (Sandbox Code Playgroud)
现在......正如@Jonathan注意到的那样,你回来了IEnumerable<>,所以你可以:
return e.Select(x => new SomeType { SomeProperty = x.OtherProperty });
Run Code Online (Sandbox Code Playgroud)
并且幸福快乐......或者你可以
private IEnumerable<SomeType> DoStuff(IEnumerable<OtherType> e)
{
foreach (var elem in e)
{
yield return new SomeType
{
SomeProperty = elem.OtherProperty
};
}
}
Run Code Online (Sandbox Code Playgroud)
(这几乎等同于做Select,但如果你有一个复杂的表达式来转换元素,也许使用Select变得很麻烦)
或者,如果您真的想要创建List<>并在可能的情况下进行预设:
ICollection<T> c = e as ICollection<T>;
int count = c != null ? c.Count : 0;
var list = new List<SomeType>(count);
Run Code Online (Sandbox Code Playgroud)
一如既往,请记住,除非你真的确定,否则你不应该IEnumerable<>多次枚举
List<>伪装的一个或其他集合,因此数据已经存在,并且多次枚举它没有问题要么
IEnumerable<>枚举它都将从头开始重建,但成本可以忽略不计.