Стоит ли увлекаться лямбдами?
От: Neco  
Дата: 12.10.10 19:23
Оценка:
В последнее время всё чаще строю многоэтажные конструкции типа:
            xml.Div(new { @class = "editor-area" }, () => {
                if (!HideBackButton()) {
                    xml.PTag(() => {
                        xml.ImageActionRef(Page.Content.ImgUrl(IMG_PREVIOUS_BUTTON), "To the List", ActionNameForBackButton(), "Back to the List", ParentListRoutes());
                    });
                }

                xml.FieldSet((fieldset) => {
                    fieldset.Legend(LegendText());

                    if (!string.IsNullOrEmpty(model.ErrorMessage)) {
                        xml.Div(new { @class = "error-message" }, () => {
                            xml.WriteString(model.ErrorMessage);
                        });
                    }
                    if (model.Exception != null) {
                        xml.Div(new { @class = "error-exception" }, () => {
                            xml.PrintException(model.Exception);
                        });
                    }

                    xml.ComplexFieldHidden(GetLambdaFroSerializedObject(m => m.SerializedOriginalModel), model.SerializedOriginalModel);

                    if (fields != null) {
                        foreach (var one_field in fields) {
                            one_field.Render(xml);
                        }
                    } else if (customFields != null) {
                        customFields(xml);
                    } else {
                        throw new InvalidOperationException("Do not have any field for render!");
                    }

                    if (! this.HideSubmitButton())
                    {
                        xml.SubmitButton("Submit");
                    }
                });
            });

помеченные жирным конструкции могут вкладываться друг в друга весьма глубоко, если не в одном методе, то в их последовательном вызове. Вовсю используются замыкания.
в данном случае, это как бы Presentation, но планирую использовать такой же подход на уровне контроллеров и вообще по жизни.
Так вопрос, чем это может грозить? Потерей производительности, например?
Слышал что-то, что бинарники бУхнут от таких конструкций (из-за количества анонимных классов), но меня это мало беспокоит. Или должно беспокоить, как считаете?
всю ночь не ем, весь день не сплю — устаю
Re: Стоит ли увлекаться лямбдами?
От: Lloyd Россия  
Дата: 12.10.10 19:27
Оценка: 1 (1) +5
Здравствуйте, Neco, Вы писали:

N>в данном случае, это как бы Presentation, но планирую использовать такой же подход на уровне контроллеров и вообще по жизни.

N>Так вопрос, чем это может грозить? Потерей производительности, например?
N>Слышал что-то, что бинарники бУхнут от таких конструкций (из-за количества анонимных классов), но меня это мало беспокоит. Или должно беспокоить, как считаете?

Я бы беспокоился больше по поводу читабельности. А она, по-моему, в приведенном примере хромает на обе ноги.
Re[2]: Стоит ли увлекаться лямбдами?
От: Neco  
Дата: 12.10.10 23:36
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Я бы беспокоился больше по поводу читабельности. А она, по-моему, в приведенном примере хромает на обе ноги.

Хех-хех, да это есть ))
Но пока идей, как это улучшить, нет. Может у Вас есть? Буду признателен.
всю ночь не ем, весь день не сплю — устаю
Re[3]: Стоит ли увлекаться лямбдами?
От: MozgC США http://nightcoder.livejournal.com
Дата: 12.10.10 23:45
Оценка:
Здравствуйте, Neco, Вы писали:

N>Но пока идей, как это улучшить, нет. Может у Вас есть? Буду признателен.


— Не использовать многоэтажные лямбда-конструкции?
Re[3]: Стоит ли увлекаться лямбдами?
От: Neco  
Дата: 12.10.10 23:53
Оценка:
Здравствуйте, Neco, Вы писали:

N>Здравствуйте, Lloyd, Вы писали:


L>>Я бы беспокоился больше по поводу читабельности. А она, по-моему, в приведенном примере хромает на обе ноги.

N>Хех-хех, да это есть ))
N>Но пока идей, как это улучшить, нет. Может у Вас есть? Буду признателен.
Кстати, раз уж я спрашиваю про идею, то пожалуй скажу для чего такая конструкция нужна (чтобы можно было исходя из требования что-то предлагать, а не из кода). По сути нужно иметь возможность повторно использовать элементы дизайна. В моём случае это Asp.Net MVC, хотя от оригинала уже мало что осталось. Проблема зародилась в том, что при объединении нескольких mvc-контролов в один более сложный (например, кнопка с текстом — т.е. по сути гиперлинк с картинкой и текстом внутри), предлагалось либо не париться и дублировать, либо писать своё расширение, код которого в общем-то, будет состоять из бубнов с TagBuilder'ом. И сделать такой код повторно используемым я не понял как. Постепенно пришёл к тому, что всякое расширение любого html элемента, который может в себе что-то содержать, должно принимать параметр-лямбду, типа subHtml. Если сообщать вместо лямбды string, то визуально нарушается ход событий (т.е. сначала готовим начинку, а потом её используем). Таким образом такая конструкция и случилась.
всю ночь не ем, весь день не сплю — устаю
Re[4]: Стоит ли увлекаться лямбдами?
От: Neco  
Дата: 12.10.10 23:58
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>- Не использовать многоэтажные лямбда-конструкции?

Это логично, но они неспроста появились — т.е. они решают вполне конкретную задачу.
В общем, я Lloyd'у написал подробное объяснение.
всю ночь не ем, весь день не сплю — устаю
Re[3]: Стоит ли увлекаться лямбдами?
От: Lloyd Россия  
Дата: 13.10.10 00:13
Оценка:
Здравствуйте, Neco, Вы писали:

L>>Я бы беспокоился больше по поводу читабельности. А она, по-моему, в приведенном примере хромает на обе ноги.

N>Хех-хех, да это есть ))
N>Но пока идей, как это улучшить, нет. Может у Вас есть? Буду признателен.

Если честно, я даже не понял что там написано.
Re: Стоит ли увлекаться лямбдами?
От: _FRED_ Черногория
Дата: 13.10.10 03:00
Оценка: 8 (2) +1
Здравствуйте, Neco, Вы писали:

N>В последнее время всё чаще строю многоэтажные конструкции типа:


ИМХО, ничего страшного нет.

N>            xml.Div(new { @class = "editor-area" }, () => {
N>                if (!HideBackButton()) {
N>                    xml.PTag(() => {
                          // сделать разве что "поуже", не так широко,
                          // перенеся длинные строки на несколько строк.
N>                        xml.ImageActionRef(Page.Content.ImgUrl(IMG_PREVIOUS_BUTTON), 
                              "To the List", ActionNameForBackButton(), 
                              "Back to the List", ParentListRoutes());
N>                    });
N>                }

                  // убрал бы скобки вокруг одного параметра лямбды
N>                //xml.FieldSet((fieldset) => {
                  xml.FieldSet(fieldset => {
N>                    fieldset.Legend(LegendText());

N>                    if (!string.IsNullOrEmpty(model.ErrorMessage)) {
N>                        xml.Div(new { @class = "error-message" }, 
                              // А тут убрал бы не обязательные скобки.
                              () => xml.WriteString(model.ErrorMessage););
N>                    }
N>                    if (model.Exception != null) {
N>                        xml.Div(new { @class = "error-exception" },
                              // И тут.
                              () => xml.PrintException(model.Exception););
N>                    }

N>                    xml.ComplexFieldHidden(
                          GetLambdaFroSerializedObject(m => m.SerializedOriginalModel),
                          model.SerializedOriginalModel);

N>                    if (fields != null) {
N>                        foreach (var one_field in fields) {
N>                            one_field.Render(xml);
N>                        }
N>                    } else if (customFields != null) {
N>                        customFields(xml);
N>                    } else {
N>                        throw new InvalidOperationException("Do not have any field for render!");
N>                    }

                      // Этот абзац сильвы выбивается из общего стиля:
                      // скобки не так расставлены, "this." …
N>                    if (!HideSubmitButton()) {
N>                        xml.SubmitButton("Submit");
N>                    }
N>                });
N>            });


Так же (но это уже не совсем к читабельности, хотя может и к ней) смущает "new { @class = "editor-area" }" — набор атрибутов не на столько большой, что бы сложно было бы описать один единственный раз его и пользщоваться далее уже типизированными аналогами.

N>помеченные жирным конструкции могут вкладываться друг в друга весьма глубоко, если не в одном методе, то в их последовательном вызове. Вовсю используются замыкания.

N>в данном случае, это как бы Presentation, но планирую использовать такой же подход на уровне контроллеров и вообще по жизни.
N>Так вопрос, чем это может грозить? Потерей производительности, например?

Ну это вряд ли.

N>Слышал что-то, что бинарники бУхнут от таких конструкций (из-за количества анонимных классов), но меня это мало беспокоит. Или должно беспокоить, как считаете?


Я бы не беспокоился.
Help will always be given at Hogwarts to those who ask for it.
Re: Стоит ли увлекаться лямбдами?
От: GlebZ Россия  
Дата: 13.10.10 06:36
Оценка: +4
Здравствуйте, Neco, Вы писали:

N>в данном случае, это как бы Presentation, но планирую использовать такой же подход на уровне контроллеров и вообще по жизни.

У лямбд есть существенный недостаток. Это неимение имени. Имя — это ясный абстрактный коментарий того, что данный код делает. Неимение имени существенно снижает читабельность а следовательно сопровождаемость кода. Поэтому для сложных конструкций, где с одного взгляда не поймешь что делегат делает, именованные функции рулят.


N>Так вопрос, чем это может грозить? Потерей производительности, например?

N>Слышал что-то, что бинарники бУхнут от таких конструкций (из-за количества анонимных классов), но меня это мало беспокоит. Или должно беспокоить, как считаете?
Не должно, ежели это не битовыжимательство.
Re: Стоит ли увлекаться лямбдами?
От: DuШes  
Дата: 13.10.10 07:21
Оценка:
Здравствуйте, Neco, Вы писали:
[...]

рекомендую посмотреть пост Andir в свое блоге Цикл как самый выразительный способ перебора элементов...это что касается читабельности, а в остальном полностью соглашусь с GlebZ
Re: Стоит ли увлекаться лямбдами?
От: master_of_shadows Беларусь  
Дата: 13.10.10 10:25
Оценка: +1
Здравствуйте, Neco, Вы писали:

N>Так вопрос, чем это может грозить? Потерей производительности, например?


Мне в лямбдах не нравится стектрейс при эксепшене. Неприятно его разгребать .
Re: Стоит ли увлекаться лямбдами?
От: xvost Германия http://www.jetbrains.com/company/people/Pasynkov_Eugene.html
Дата: 13.10.10 12:14
Оценка: +1
Здравствуйте, Neco, Вы писали:

N>Слышал что-то, что бинарники бУхнут от таких конструкций (из-за количества анонимных классов), но меня это мало беспокоит. Или должно беспокоить, как считаете?


По поводу лямбд стоит беспокоиться в Performance-critical местах, поскольку они ОЧЕНЬ небесплатны по производительности
С уважением, Евгений
JetBrains, Inc. "Develop with pleasure!"
Re[2]: Стоит ли увлекаться лямбдами?
От: _FRED_ Черногория
Дата: 13.10.10 12:41
Оценка:
Здравствуйте, xvost, Вы писали:

N>>Слышал что-то, что бинарники бУхнут от таких конструкций (из-за количества анонимных классов), но меня это мало беспокоит. Или должно беспокоить, как считаете?


X>По поводу лямбд стоит беспокоиться в Performance-critical местах, поскольку они ОЧЕНЬ небесплатны по производительности


По сравнению с вызовом именованного метода?
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Стоит ли увлекаться лямбдами?
От: xvost Германия http://www.jetbrains.com/company/people/Pasynkov_Eugene.html
Дата: 13.10.10 12:50
Оценка: 8 (1)
Здравствуйте, _FRED_, Вы писали:

X>>По поводу лямбд стоит беспокоиться в Performance-critical местах, поскольку они ОЧЕНЬ небесплатны по производительности

_FR>По сравнению с вызовом именованного метода?

Во-первых да.
Во-вторых там не только вызов, а еще
2а) Создание объекта-замыкания
2б) Создание делегата над методом класса замыкания

Все это во-первых весьма и весьма жрет ЦПУ (учитывая подводные и широко неизвестные факты в EE про создания лямбд над методом класса с дженериками)
А во-вторых объекты замыкания, если их много, весьма основательно мусорят, что приводит к mid-life crisis'у
С уважением, Евгений
JetBrains, Inc. "Develop with pleasure!"
Re[4]: Стоит ли увлекаться лямбдами?
От: _FRED_ Черногория
Дата: 13.10.10 13:13
Оценка: 1 (1) +2
Здравствуйте, xvost, Вы писали:

X>>>По поводу лямбд стоит беспокоиться в Performance-critical местах, поскольку они ОЧЕНЬ небесплатны по производительности

_FR>>По сравнению с вызовом именованного метода?

X>Во-первых да.

X>Во-вторых там не только вызов, а еще
X> 2а) Создание объекта-замыкания

Я так понимаю, что вряд-ли "Создание объекта-замыкания" отличается от просто создания (и инициализации) некоторого пользовательского объекта с такими же полями?

Конечно, считая относительно медленным создание любого объекта, можно придти к тому, что лямбды тормозят. Надеюсь, такие подсчёты не станут обычными для большинства прогоаммистов

Или создание именно "объекта-замыкания" обычно медленнее, чем создание пользовательского объекта?

X> 2б) Создание делегата над методом класса замыкания


Делегат тоже создаётся заметно медленнее чем обычный пользовательский объект?

X>Все это во-первых весьма и весьма жрет ЦПУ (учитывая подводные и широко неизвестные факты в EE про создания лямбд над методом класса с дженериками)


Разве EE знает, с объектом лямбды она дело имеет просто с пользовательским объектом/методом и не знает, что когда-то обыло лямбдой? Мне казалось, что "лямбда" — лишь понятия компилятора, а EE уже дела нет, что это за объект. Это не так? Другими словами, чем отличается поведение ЕЕ "про создания лямбд над методом класса с дженериками" от "про создания делегатов над методом класса с дженериками"?

X>А во-вторых объекты замыкания, если их много, весьма основательно мусорят, что приводит к mid-life crisis'у


А что можно назвать "mid-life crisis"-ом применительно к данному вопросу?
Help will always be given at Hogwarts to those who ask for it.
Re[5]: Стоит ли увлекаться лямбдами?
От: xvost Германия http://www.jetbrains.com/company/people/Pasynkov_Eugene.html
Дата: 13.10.10 13:17
Оценка: 49 (2)
Здравствуйте, _FRED_, Вы писали:

_FR>Я так понимаю, что вряд-ли "Создание объекта-замыкания" отличается от просто создания (и инициализации) некоторого пользовательского объекта с такими же полями?


правильно.

X>> 2б) Создание делегата над методом класса замыкания

_FR>Делегат тоже создаётся заметно медленнее чем обычный пользовательский объект?

Да. Создание делегата — во много раз более дорогое удовольствие чем создание простого объекта

_FR>Разве EE знает, с объектом лямбды она дело имеет просто с пользовательским объектом/методом и не знает, что когда-то обыло лямбдой? Мне казалось, что "лямбда" — лишь понятия компилятора, а EE уже дела нет, что это за объект. Это не так? Другими словами, чем отличается поведение ЕЕ "про создания лямбд над методом класса с дженериками" от "про создания делегатов над методом класса с дженериками"?


Еще раз. Никаких лямбд в EE нет. Там есть только делегаты. А их создание — очень и очень дорогое удовольствие. К тому же (при определенных условиях) блокирующее, что немедленно сказывается на многопоточных приложениях

X>>А во-вторых объекты замыкания, если их много, весьма основательно мусорят, что приводит к mid-life crisis'у

_FR>А что можно назвать "mid-life crisis"-ом применительно к данному вопросу?

Пользовательская логика. Ее объекты передут в Gen1 тогда как могли бы умереть в Gen0
С уважением, Евгений
JetBrains, Inc. "Develop with pleasure!"
Re[6]: Стоит ли увлекаться лямбдами?
От: _FRED_ Черногория
Дата: 13.10.10 13:22
Оценка:
Здравствуйте, xvost, Вы писали:

X>>> 2б) Создание делегата над методом класса замыкания

_FR>>Делегат тоже создаётся заметно медленнее чем обычный пользовательский объект?

X>Да. Создание делегата — во много раз более дорогое удовольствие чем создание простого объекта


ОК, это объясняет назойливое кэширование, когда это возможно, делегатов.

_FR>>Разве EE знает, с объектом лямбды она дело имеет просто с пользовательским объектом/методом и не знает, что когда-то обыло лямбдой? Мне казалось, что "лямбда" — лишь понятия компилятора, а EE уже дела нет, что это за объект. Это не так? Другими словами, чем отличается поведение ЕЕ "про создания лямбд над методом класса с дженериками" от "про создания делегатов над методом класса с дженериками"?


X>Еще раз. Никаких лямбд в EE нет. Там есть только делегаты. А их создание — очень и очень дорогое удовольствие.


ОК, я всего лишь пытался понять ваши же слова:

…(учитывая подводные и широко неизвестные факты в EE про создания лямбд над методом класса с дженериками)



X>К тому же (при определенных условиях) блокирующее, что немедленно сказывается на многопоточных приложениях


Спасибо, будет что посмотреть.

X>>>А во-вторых объекты замыкания, если их много, весьма основательно мусорят, что приводит к mid-life crisis'у

_FR>>А что можно назвать "mid-life crisis"-ом применительно к данному вопросу?
X>Пользовательская логика. Ее объекты передут в Gen1 тогда как могли бы умереть в Gen0

О как интересно: и термин здоровский, и не бросается так сразу в глаза.
Help will always be given at Hogwarts to those who ask for it.
Re[6]: Стоит ли увлекаться лямбдами?
От: _FRED_ Черногория
Дата: 13.10.10 13:28
Оценка: 6 (1)
Здравствуйте, xvost, Вы писали:

X>>> 2б) Создание делегата над методом класса замыкания

_FR>>Делегат тоже создаётся заметно медленнее чем обычный пользовательский объект?

Кстати, получается, если в примере топикстартера, например, мы заменим все лямбды на обычные, именованные методы или именованные методы во вспомагательных классах, то (поскольку и создание вспомагательных классов и создание делегатов останется) прироста производительности всё-таки не получится?

То есть, да: использование API, основанного на вызове методов через делегаты (linq/Rx и многое уже что появилось) уже чревато (из-за дороговизны создания делегата) но использование этого API посредстром анонимных методов или лямбд с точки зрения производительности всё-тки не хуже использования этого же API посредством именованных методов?

Надеюсь, не слишком завернул
Help will always be given at Hogwarts to those who ask for it.
Re[7]: Стоит ли увлекаться лямбдами?
От: xvost Германия http://www.jetbrains.com/company/people/Pasynkov_Eugene.html
Дата: 13.10.10 13:52
Оценка: 26 (1) +4
Здравствуйте, _FRED_, Вы писали:

_FR>но использование этого API посредстром анонимных методов или лямбд с точки зрения производительности всё-тки не хуже использования этого же API посредством именованных методов?


В общем, да. Разницу в микроскоп будет не заметить.

И все приведенные мною выше слова относятся действительно к performance-critical коду, который вызывается десятки тысяч раз в секунду. Там использование лямбд, linq и прочей современной радости _строго_ противопоказано.

Во всех остальных случаях, как правило, удобство чтения, восприятия и модификации кода перевешивает перфоманс-деградацию
С уважением, Евгений
JetBrains, Inc. "Develop with pleasure!"
Re[7]: Стоит ли увлекаться лямбдами?
От: Jolly Roger  
Дата: 13.10.10 14:02
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>То есть, да: использование API, основанного на вызове методов через делегаты (linq/Rx и многое уже что появилось) уже чревато (из-за дороговизны создания делегата) но использование этого API посредстром анонимных методов или лямбд с точки зрения производительности всё-тки не хуже использования этого же API посредством именованных методов?


В NET альтернатива делегату, по-моему, только интерфейс, то есть выбор не особо велик, а созданный делегат, в том числе и на базе анонима, можно "кэшировать". Кстати, кто-нибудь интересовался, при использовании лямбд кэширование выполняется?
"Нормальные герои всегда идут в обход!"
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.