Я тестирую различия в производительности, используя различные синтаксисы лямбда-выражений.Если у меня есть простой метод:
public IEnumerable<Item> GetItems(int point)
{
return this.items.Where(i => i.IsApplicableFor(point));
}
, то здесь происходит подъем переменной, связанный с параметром point
, потому что это свободная переменная с точки зрения лямбды.Если бы я назвал этот метод миллион раз, было бы лучше оставить его как есть или изменить его каким-либо образом, чтобы улучшить его производительность?
Какие варианты у меня есть и какие на самом деле есть?возможно? Насколько я понимаю, мне нужно избавиться от свободных переменных, чтобы компилятору не приходилось создавать класс замыкания и создавать его экземпляры при каждом вызове этого метода.Это создание обычно занимает значительное количество времени по сравнению с незакрытыми версиями.
Дело в том, что я хотел бы придумать какое-то лямбда-руководство по написанию , которое обычно работает, потому что оноКажется, я теряю время каждый раз, когда пишу сильно лямбда-выражение.Я должен вручную проверить его, чтобы убедиться, что он будет работать, потому что я не знаю, каким правилам следовать.
Альтернативный метод
и пример кода консольного приложения
IМы также написали другую версию того же метода, который не требует поднятия переменной (по крайней мере, я думаю, что это не так, но вы, ребята, которые понимают это, дайте мне знать, если это так):
public IEnumerable<Item> GetItems(int point)
{
Func<int, Func<Item, bool>> buildPredicate = p => i => i.IsApplicableFor(p);
return this.items.Where(buildPredicate(point));
}
Проверьте Суть здесь .Просто создайте консольное приложение и скопируйте весь код в файл Program.cs
внутри блока namespace
.Вы увидите, что второй пример намного медленнее, хотя он и не использует свободные переменные.
Противоречивый пример
Причина, по которой я хотел бы построить лучшую лямбду Руководство по использованию состоит в том, что я столкнулся с этой проблемой до , и, к моему удивлению, одна из них работала быстрее, когда использовалось построитель предикатов лямбда-выражение.
Теперь объясните это тогда.Я совершенно потерян, потому что может оказаться, что я не буду использовать лямбда-выражения вообще, когда знаю, что в моем коде есть какой-то метод интенсивного использования.Но я хотел бы избежать такой ситуации и разобраться во всем этом.
Редактировать
Ваши предложения не работают
Я пытался реализоватьПользовательский класс поиска, который внутренне работает аналогично тому, что компилятор делает со свободной переменной lambda.Но вместо того, чтобы иметь класс замыкания, я реализовал элементы экземпляров, которые имитируют похожий сценарий.Это код:
private int Point { get; set; }
private bool IsItemValid(Item item)
{
return item.IsApplicableFor(this.Point);
}
public IEnumerable<TItem> GetItems(int point)
{
this.Point = point;
return this.items.Where(this.IsItemValid);
}
Интересно, что это работает так же медленно, как и медленная версия.Я не знаю почему, но, кажется, ничего не делает, кроме быстрого.Он использует те же функциональные возможности, потому что эти дополнительные члены являются частью одного и того же экземпляра объекта.Тем не мение. Я сейчас в замешательстве !
Я обновил Источник Gist с этим последним дополнением, так что вы можете проверить себя.