Здравствуйте, gandjustas, Вы писали:
G>>>Что такое "данимические замыкания" ? В IL замыкания превращаются просто в классы.
EP>>При этом передаются через параметры, сохраняются в классы и т.п. посредством динамического полиморфизма, стирая исходный тип.
G>Ты бредишь
Хамство это конечно отличный, а главное конструктивный аргумент. Зачем думать, анализировать, спрашивать — когда можно просто нахамить — "не понимаю значит бред"
G>В замыканиях нетполиморфизма
Не в самих замыканиях. Напиши пример ФВП которая принимает простейшее замыкание.
G>>>Что такое "динамический IEnumerable"?
EP>>Динамический полиморфизм для обхода последовательностей.
G>Пример кода покажи, не ясно о чем ты пишешь.
Вот.
G>>>Это в смысле IEnumerable не по массивам? Зачем его использовать в performance-critical коде?
EP>>Затем что последовательности могут быть выражены разными структурами данных.
G>Не пойму о чем ты.
std::vector, std::deque, std::string — это всё random access последовательности. На них можно писать алгоритмы на итераторах, без abstraction penalty.
На C# IList даст приличную просадку. И это лишь один из примеров.
EP>>Собственно о том и речь — в C++ я могу накручивать уровни абстракций даже в performance-critical коде, без жёсткого penalty.
G>Это только если инлайнинг сработает.
И что характерно он работает, потому что язык к этому располагает. Потому что можно использовать ФВП, замыкания, и т.п. без всякого динамического полиморфизма.
G>>>А IEnumerable (foreach) с массивами действительно тормозит (накладные расходы на Enumerator оказываются больше, чем затратры на тело цикла). Как раз из-за недостатка инлайнинга, в C++ foreach нилайнится.
EP>>Так дело не в самом foreach — ты если распишешь его вручную, то он также будет тормозить, за счёт динамического полиморфизма..
G>Для обычных массивов jit оптимизирует foreach
Вообще-то про foreach начал говорить ты, сначала сказал что тормозит, потом привёл пример где не тормозит. Круто чё.
Я же говорил про
IEnumerable.
G>C IEnumerable другая проблема, которая связана с ФВП. Вообще ФП в C# довольно медленно работает, не создавался язык под него.
О чём и речь
G>>>Или ты имеешь ввиду использование ФВП для обхода массивов? Оно действительно и в C++, и в C# плохо работает. И в C++ и в C# такой код вручную оптимизируется.
EP>>ФВП в том числе. А с чего ты взял что они в C++ плохо работают? Наоборот, прекрасно работают и отлично оптимизируются.
EP>>Пример C++ -> JS vs C# как раз ФВП и использует.
G>За счет инлайнинга, который JIT не делает.
G>Но ты же не будешь в performance-critical на автоматический инлайнинг полагаться.
Так в том-то и фишка что буду, because I can! Зачем мне делать его руками, для всех используемых комбинаций алгоритмов * замыканий * последовательностей * прочих абстракций, когда с этим прекрасно справляется компилятор?
Там где это критично — проверю сгенерированный код, сделаю замеры — и добавлю простой тест с замерами на эту тему
G>>>>>Машинный код генерируется из IL. В нем все указанные тобой оптимизации делаются элементарно.
G>>>>>Но у JIT нет столько времени на пребразования, как у компилятора C++.
EP>>>>Что мешает сразу генерировать оптимизированный IL?
G>>>IL — высокоуровневый язык. Он и так достаточно оптимален на своем уровне.
EP>>И что из этого? C# версия без ФВП тоже компилируется в тот же самый "высокоуровневый IL", но работает быстрее. Версия с ФВП могла бы давать точно такой же IL.
G>Не могла бы, потому что делегаты.
То есть таки язык мешает оптимизациям?
G>>>Работает быстро за счет "hotspot". Большинство движков JS перекомпилируют код на основании профиля использования. Кроме того "работает быстро" — это когда не используются ФВП.
EP>>Вот именно, в исходном коде на C++ были ФВП и замыкание, в результирующем JS они были выоптимизированы компилятором C++, так как это элементарная операция (никакого динамического полиморфизма) — именно поэтому и быстро.
G>Ну так ты продолжаешь доказывать, что проблема в языке C#.
Проблема в языке в том числе, за счёт повсеместного динамического полиморфизма и избыточных индерекций по памяти.