в чем разница между циклом for (или) foreach и запросом linq в случае скорости - PullRequest
1 голос
/ 21 октября 2010

Я хотел бы знать, что различие извлекается из списка, используя цикл forach (или) foreach, и извлекается из списка, используя запрос linq. особенно в случае скорости и другой разницы

Пример:

Список A = новый список () содержит 10000 строк, которые мне нужно скопировать, отфильтровать несколько строк из списка А, что лучше в случае скорости, с которой я работаю для цикла или запроса linq

Ответы [ 2 ]

3 голосов
/ 21 октября 2010

Вы можете сравнить себя и узнать. (В конце концов, только вы знаете конкретные обстоятельства, при которых вам нужно будет выполнять эти циклы и запросы.)

Мое (очень грубое) эмпирическое правило - в котором так много предостережений и исключений, что оно почти бесполезно, - это то, что цикл for обычно будет немного быстрее, чем foreach, который обычно будет немного быстрее, чем разумно написанный запрос LINQ.

Вы должны использовать любую конструкцию, наиболее подходящую для вашей конкретной ситуации. Если то, что вы хотите сделать, лучше всего выражено с помощью цикла for, то сделайте это; если это лучше всего выражено как foreach, тогда сделайте это; если это лучше всего выражено как запрос, используйте LINQ.

Только , если и когда вы обнаружите, что производительность недостаточна , если вы подумаете о переписывании кода, который выразителен и исправлен, во что-то более быстрое и менее выразительное (но, надеюсь, все еще правильное).

2 голосов
/ 21 октября 2010

Если мы говорим о обычном LINQ, то мы фокусируемся на IEnumerable<T> (LINQ-to-Objects) и IQueryable<T> (LINQ-to-большинству других вещей).Начиная с IQueryable<T> : IEnumerable<T>, вы можете автоматически использовать foreach, но это означает, что очень специфично для запроса, поскольку LINQ обычно лениво спулингует данные из базового источника.Действительно, этот источник может быть бесконечным:

public IEnumerable<int> Forever() {
    int i = 0;
    while(true) yield return i++;
}
...
foreach(int i in Forever()) {
    Console.WriteLine(i);
    if(Console.ReadLine() == "exit") break;
}

Однако для цикла for требуется длина и индексатор .Что в реальном выражении обычно означает вызов ToList() или ToArray():

var list = source.ToList();
for(int i = 0 ; i < list.Count ; i++) { do something with list[i] }

Это интересно по-разному: во-первых, он умрет для бесконечных последовательностей; p .Тем не менее, это также перемещает буферизацию раньше.Так что если мы будем читать из внешнего источника данных, цикл for / foreach по списку будет быстрее, но просто потому, что мы переместили большую работу на ToList() (илиToArray() и т. Д.)

Еще одна важная особенность выполнения ToList() ранее заключается в том, что вы закрыли считыватель .Вам может нужно работать с данными внутри списка, и это не всегда возможно, когда читатель открыт;например, итераторы ломаются при перечислении - или, что еще важнее, если вы не используете «MARS», SQL Server допускает только одно чтение на соединение.В качестве контрапункта, который пахнет "n + 1", так что следите за этим тоже.

Для локального списка / массива / и т. Д., В значительной степени избыточно, какую стратегию цикла вы используете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...