<ul>
<li ng-repeat="item in items | filter:keyword as filteredItems">
...
</li>
<li ng-if="filteredItems.length===0">
No items found
</li>
</ul>
Это похоже на @Konrad 'ktoso' Malawski, но немного легче запомнить.
Протестировано с Angular 1.4
Напишите максимально понятный код, а затем выполните тест и профилируйте, чтобы обнаружить любые проблемы с производительностью. Если у вас действительно есть проблемы с производительностью, вы можете поэкспериментировать с другим кодом, чтобы выяснить, быстрее он или нет (постоянно измеряя с максимально реалистичными данными), а затем сделать вывод о том, улучшилось ли улучшение. в производительности стоит удар по удобочитаемости.
Прямой подход foreach
во многих случаях будет быстрее, чем LINQ. Например, рассмотрим:
var query = from element in list
where element.X > 2
where element.Y < 2
select element.X + element.Y;
foreach (var value in query)
{
Console.WriteLine(value);
}
Теперь есть два предложения where
и предложение select
, поэтому каждый конечный элемент должен пройти через три итератора. (Очевидно, что в этом случае можно было бы объединить два предложения where, но я делаю общий вывод.)
Теперь сравните его с прямым кодом:
foreach (var element in list)
{
if (element.X > 2 && element.Y < 2)
{
Console.WriteLine(element.X + element.Y);
}
}
Это будет работать быстрее, потому что у него будет меньше обручей. Скорее всего, вывод на консоль будет значительно превышать стоимость итератора, и я определенно предпочитаю LINQ-запрос.
РЕДАКТИРОВАТЬ: Чтобы ответить о «вложенных циклах foreach» ... обычно они представлены с помощью SelectMany
или второй из предложения
:
var query = from item in firstSequence
from nestedItem in item.NestedItems
select item.BaseCount + nestedItem.NestedCount;
Здесь мы добавляем только один дополнительный итератор, потому что мы уже использовали бы дополнительный итератор для каждого элемента в первой последовательности из-за вложенного цикл foreach
. По-прежнему есть небольшие накладные расходы, включая накладные расходы на выполнение проекции в делегате вместо "встроенного" (о чем я не упоминал раньше), но это все равно не будет сильно отличаться от производительности вложенного foreach.
Это не значит, что ты можешь » С LINQ, конечно, стрелять себе в ногу. Вы можете писать чрезвычайно неэффективные запросы, если сначала не задействуете свой мозг - но это далеко не уникально для LINQ ...
Если вы выполните
foreach(Customer c in Customer)
{
foreach(Order o in Orders)
{
//do something with c and o
}
}
, вы выполните итерации Customer.Count * Order.Count
Если вы выполните
var query =
from c in Customer
join o in Orders on c.CustomerID equals o.CustomerID
select new {c, o}
foreach(var x in query)
{
//do something with x.c and x.o
}
, вы выполните итерации Customer.Count + Order.Count, потому что Enumerable .Join реализован как HashJoin.
Это более сложный вопрос. В конечном счете, большая часть LINQ-to-Objects (за кулисами) представляет собой цикл foreach
, но с дополнительными накладными расходами в виде небольших блоков абстракции / итератора / и т. Д. Однако, если вы не делаете совсем другие вещи в своем две версии (foreach против LINQ), обе должны быть O (N).
Реальный вопрос: есть ли лучший способ написать свой конкретный алгоритм, который означает, что foreach
будет неэффективным? Может ли LINQ сделать это за вас?
Например, LINQ упрощает хэширование / группировку / сортировку данных.
Об этом уже говорилось, но стоит повторить.
Разработчики никогда не узнают, где находится узкое место производительности, пока не проведут тесты производительности.
То же самое можно сказать и о сравнении техники А с техникой Б. Если нет существенной разницы, вам просто нужно ее проверить. Это может быть очевидно, если у вас есть сценарий O (n) vs O (n ^ x), но поскольку материал LINQ в основном является колдовством компилятора, он заслуживает профилирования.
Кроме того, если ваш проект не находится в производстве, и вы профилировали код и обнаружили, что этот цикл замедляет ваше выполнение, оставьте его, в зависимости от того, что вы предпочитаете для удобочитаемости и обслуживания. Дьявол - преждевременная оптимизация.
Большим преимуществом является то, что использование запросов Linq-To-Objects дает вам возможность легко переключить запрос в PLinq и заставить систему автоматически выполнять операцию с правильным количеством потоков для текущая система.
Если вы используете этот метод для больших наборов данных, это легко превратиться в большую победу при очень небольших проблемах.