2013-08-09 3 views
4

В коде Im поддерживается общий шаблон, такой как следующий, вложенный цикл с if, чтобы найти определенные элементы.LINQ vs inested loop

 foreach (Storage storage in mStorage.Values) 
      foreach (OrderStorage oStorage in storage.OrderStorage) 
       if (oStorage.OrderStorageId == orderStorageId) 

Я думал, чтобы изменить это в LINQ:

 foreach (OrderStorage oStorage in (from storage in mStorage.Values 
              from oStorage in storage.OrderStorage 
              where oStorage.OrderStorageId == orderStorageId 
              select oStorage)) 

Но это не кажется, все, что привлекательным, потому что это менее прозрачны, что происходит здесь, больше объектов могут быть созданы калькуляции производительности с точки зрения как памяти и процессора. Будет ли создано больше объектов или компилятор C# испускает код, похожий на вложенный цикл с if, если внутри?

+3

[Если у вас есть две лошади, и вы хотите знать, какая из них быстрее, чем ** расы ваших лошадей **.] (Http://ericlippert.com/2012/12/17/performance-rant/) –

ответ

14

Будет ли создано больше объектов или код компилятора C# испускает код, похожий на вложенный цикл с if внутри?

Больше объектов; каждая операция LINQ (SelectMany, Where, Select и т. д.) приведет к созданию нового объекта-владельца места, который представляет ожидающий IEnumerable<T> запрос этой операции, а затем, когда он окончательно повторится, каждый из них приведет к экземпляру перечислителя, а также контекст и т.д. Плюс есть трофейный переменный контекст для поднятого orderStorageId и т.д.

Обратите внимание, что регулярное foreach также приведет к экземпляру перечислителей, но foreach имеет то преимущество, что он также может использовать утиные типизированные счетчики - что означает, что для таких вещей, как List<T>, на самом деле используется счетчик struct, а не нумератор class. И, конечно, использование локальной переменной (orderStorageId) напрямую (а не анонимным методом) означает, что ее не нужно поднимать в объект state/context.

Так что да, сырье foreach является более прямым и эффективным. Интересный вопрос: есть разница important. Иногда это так, иногда это не так.

+0

thats вид информации, который я искал, спасибо – Laurijssen

+1

Согласитесь с @marcgravell, что есть перфективный хит с LINQ, но он позволяет потенциально увеличить ремонтопригодность и потенциально облегчить параллелизм. Дилемма персидского и тупик - это то, что делает компьютерное программирование искусством. –