Является ли оператор LINQ быстрее, чем цикл "foreach"?
Я пишу менеджер рендеринга сетки и подумал, что было бы неплохо сгруппировать все сетки, которые используют один и тот же шейдер, а затем визуализировать их, пока я нахожусь в этом шейдерном проходе.
в настоящее время я использую foreach цикл, но интересно, если использование LINQ может дать мне увеличение производительности?
8 ответов:
Почему LINQ должен быть быстрее? Он также использует петли внутри.
в большинстве случаев LINQ будет немного медленнее, потому что он вводит накладные расходы. Не используйте LINQ, если вы сильно заботитесь о производительности. Используйте LINQ, потому что вы хотите более короткий, более читаемый и поддерживаемый код.
LINQ-to-Objects вообще собирается добавить некоторые незначительные расходы (несколько итераторов и т. д.). Он все еще должен делать петли,и есть делегат вызывается, и как правило, приходится делать лишние разыменования, чтобы попасть в плен переменных и т. д. В большинстве кодов это будет практически незаметно, и больше, чем обеспечивается более простым для понимания кодом.
С другими поставщиками LINQ, такими как LINQ-to-SQL, то с тех пор запрос можно фильтровать на сервере он должен быть намного лучше чем квартира
foreach, но скорее всего вы бы не сделали одеяло"select * from foo"в любом случае, так что не обязательно честное сравнение.Re PLINQ; параллелизм может уменьшить истек время, но общее время процессора обычно немного увеличивается из-за накладных расходов на управление потоками и т. д.
Я думаю, что LINQ лучше использовать над
foreachпетли, потому что это дает вам гораздо более чистый и понятный код. Но LINQ медленнее, чемforeach. Чтобы получить больше, пройдите статью LINQ vs FOREACH vs для производительности цикла.
LINQ теперь медленнее, но в какой-то момент он может стать быстрее. Хорошая вещь о LINQ заключается в том, что вам не нужно заботиться о том, как это работает. Если новый метод придуман невероятно быстро, люди в Microsoft могут реализовать его, даже не сказав вам, и ваш код будет намного быстрее.
Что еще более важно, LINQ просто гораздо легче читать. Этого должно быть достаточно.
вы можете получить прирост производительности, если вы используете параллельный LINQ для нескольких ядер. Смотрите параллельный LINQ (PLINQ) (MSDN).
вероятно, следует отметить, что
forцикл быстрее, чемforeach. Поэтому для исходного сообщения, если вы беспокоитесь о производительности на критическом компоненте, таком как рендерер, используйтеforпетли.ссылка: в .NET, какой цикл работает быстрее, " Для " или "foreach"?
меня интересовал этот вопрос, поэтому я сделал тест только сейчас. Использование .NET Framework 4.5.2 на Intel(R) Core(TM) i3-2328M CPU @ 2.20 GHz, 2200 Mhz, 2 Core (S) с 8 ГБ оперативной памяти под управлением Microsoft Windows 7 Ultimate.
похоже, что LINQ может быть быстрее, чем для каждого цикла. вот результаты, которые я получил:
Exists = True Time = 174 Exists = True Time = 149было бы интересно, если бы некоторые из вас могли скопировать и вставить этот код в консольное приложение и протестировать его. Перед тестированием с объектом (Сотрудник) я попробовал тот же тест с целыми числами. Там линк тоже был быстрее.
public class Program { public class Employee { public int id; public string name; public string lastname; public DateTime dateOfBirth; public Employee(int id,string name,string lastname,DateTime dateOfBirth) { this.id = id; this.name = name; this.lastname = lastname; this.dateOfBirth = dateOfBirth; } } public static void Main() => StartObjTest(); #region object test public static void StartObjTest() { List<Employee> items = new List<Employee>(); for (int i = 0; i < 10000000; i++) { items.Add(new Employee(i,"name" + i,"lastname" + i,DateTime.Today)); } Test3(items, items.Count-100); Test4(items, items.Count - 100); Console.Read(); } public static void Test3(List<Employee> items, int idToCheck) { Stopwatch s = new Stopwatch(); s.Start(); bool exists = false; foreach (var item in items) { if (item.id == idToCheck) { exists = true; break; } } Console.WriteLine("Exists=" + exists); Console.WriteLine("Time=" + s.ElapsedMilliseconds); } public static void Test4(List<Employee> items, int idToCheck) { Stopwatch s = new Stopwatch(); s.Start(); bool exists = items.Exists(e => e.id == idToCheck); Console.WriteLine("Exists=" + exists); Console.WriteLine("Time=" + s.ElapsedMilliseconds); } #endregion #region int test public static void StartIntTest() { List<int> items = new List<int>(); for (int i = 0; i < 10000000; i++) { items.Add(i); } Test1(items, -100); Test2(items, -100); Console.Read(); } public static void Test1(List<int> items,int itemToCheck) { Stopwatch s = new Stopwatch(); s.Start(); bool exists = false; foreach (var item in items) { if (item == itemToCheck) { exists = true; break; } } Console.WriteLine("Exists=" + exists); Console.WriteLine("Time=" + s.ElapsedMilliseconds); } public static void Test2(List<int> items, int itemToCheck) { Stopwatch s = new Stopwatch(); s.Start(); bool exists = items.Contains(itemToCheck); Console.WriteLine("Exists=" + exists); Console.WriteLine("Time=" + s.ElapsedMilliseconds); } #endregion }
Это на самом деле довольно сложный вопрос. Linq делает некоторые вещи очень легко сделать, что если вы реализуете их самостоятельно, вы можете споткнуться (например, linq .Кроме.))( Это особенно относится к PLinq и особенно к параллельной агрегации, реализованной PLinq.
В общем, для идентичного кода linq будет медленнее из-за накладных расходов на вызов делегата.
Если, однако, вы обрабатываете большой массив данных и применяете относительно простые вычисления для элементов, вы получите огромное увеличение производительности, если:
- использовать массив для хранения данных.
вы используете цикл for для доступа к каждому элементу (в отличие от foreach или linq).
- Примечание: при бенчмаркинге, пожалуйста, все помните - если вы используете один и тот же массив/список для двух последовательных тестов, кэш процессора сделает второй быстрее. *
Comments