Возможный дубликат:
Лучше ли вызывать ToList() или ToArray() в запросах LINQ?
У меня такой код:
void Foobar(string[] arr, Dictionary<string, string[]>)
{
var t = arr.Intersect(dic.Keys).ToList(); // .or ToArray() ?
foreach(var item in t)
{
..
}
var j = t.Count; // also I need this
}
какой способ является предпочтительным?
Я мог бы обойтись без каких-либо, но мне нужно знать размер, и я не хочу называть Enumerable.Count<T>()
- кажется, делают больше действий, а затем Array<T>.Size
или List<T>.Count
. Я прав?
Ответ 1
Собственно, в текущей MS-реализации Count (IEnumerable) есть ярлык, который ищет, если IEnumerable является ICollection и вызывает Count на нем. Таким образом, производительность должна быть сопоставимой для подсчета элементов.
ToList и ToArray немного то же самое. Если IEnumerable является ICollection, тогда вместо него вызывается метод CopyTo, который немного быстрее.
Итак, выберите то, что делает ваш код наиболее читаемым, и контрольный показатель для вашего варианта использования, чтобы иметь определенный ответ.
Обновление:
Я сделал наивный бенчмарк.
Начиная с массива: var items = Enumerable.Range(1,1000).ToArray();
- вызов ToList(): 25ms/10000
- вызов ToArray(): 23 мс /10000
Начиная с IEnumerable: var items = Enumerable.Range(1,1000);
- вызов ToList(): 168 мс /10000
- вызов ToArray(): 171 мс /10000
Таким образом, вы получаете сопоставимую производительность.
Ответ 2
Если вы действительно обеспокоены производительностью, вы должны перебрать IEnumerable
и считать это, когда идете. Это позволяет избежать создания новой коллекции в целом, и пересечение нужно повторить только один раз:
void Foobar(string[] arr, Dictionary<string, string[]>)
{
var t = arr.Intersect(dic.Keys);
int count = 0;
foreach(var item in t)
{
count++;
..
}
var j = count;
}
Но, как и кто-то другой, это пахнет микро-оптимизацией. Если производительность действительно имеет значение в этой ситуации, по крайней мере, профилирование производительности, чтобы выяснить, какой метод действительно самый быстрый для вас.
Ответ 3
Разница, вероятно, настолько мала, что стоит просто использовать метод, который лучше всего соответствует вашим потребностям. Запахи микро-оптимизации.
И в этом случае, поскольку все, что вы делаете, это перечисление множества и подсчет множества (оба из которых вы можете сделать с IEnumerable), почему бы просто не оставить его как IEnumerable < > ?