Влияет ли разрыв цепочек Select () в LINQ на объекты на производительность? - PullRequest
1 голос
/ 04 мая 2010

Возьмите следующий псевдо-код C #:

using System;
using System.Data;
using System.Linq;
using System.Collections.Generic;

public IEnumerable<IDataRecord> GetRecords(string sql)
{
     // DB logic goes here
}

public IEnumerable<IEmployer> Employers()
{
     string sql = "select EmployerID from employer";
     var ids = GetRecords(sql).Select(record => (record["EmployerID"] as int?) ?? 0);
     return ids.Select(employerID => new Employer(employerID) as IEmployer);
}

Было бы быстрее, если бы два вызова Select () были объединены? Есть ли дополнительная итерация в приведенном выше коде? Следующий код быстрее?

public IEnumerable<IEmployer> Employers()
{
     string sql = "select EmployerID from employer";
     return GetRecords(sql).Select(record => new Employer((record["EmployerID"] as int?) ?? 0) as IEmployer);
}

Я думаю, что первый пример более читабелен, если нет различий в производительности.

Ответы [ 2 ]

2 голосов
/ 04 мая 2010

Нет существенной разницы. Оба метода возвращают выражение, которое может перебрать результат из GetRecords.

Они не идентичны, так как первый имеет цепочку Select, но они все равно будут выполнять ту же работу и в том же порядке. При зацикливании связанных выборок второй выбор будет располагать элементы один и один из первого выбора по мере необходимости, первый выбор не должен завершаться, прежде чем второй выбор сможет использовать результат.

0 голосов
/ 04 мая 2010

Разницы нет.

LINQ использует идею отложенной оценки, source . Я процитирую соответствующую часть:

Чтобы обойти это, все встроенные поставщики LINQ используют концепцию, известную как отложенное выполнение. Вместо того, чтобы операторы запросов выполнялись немедленно, все они просто возвращают типы, которые реализуют интерфейс IEnumerable (of T). Затем эти типы задерживают выполнение до тех пор, пока запрос фактически не будет использован для каждого цикла.

По сути, пока вы не используете результат Employers() в foreach или .ToList() и т. Д., Он фактически не выполнял никакой работы.

...