Re[27]: Да ну и фиг с этой Java-ой. .Net будет убит Rust-ом
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.08.16 21:01
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

G>>Что такое "данимические замыкания" ? В IL замыкания превращаются просто в классы.

EP>При этом передаются через параметры, сохраняются в классы и т.п. посредством динамического полиморфизма, стирая исходный тип.
Ты бредишь
1) В замыканиях нетполиморфизма
2) В замыканиях нет женериков
3) В .NET вообще нет стирания типов в женериках

G>>Что такое "динамический IEnumerable"?

EP>Динамический полиморфизм для обхода последовательностей.
Пример кода покажи, не ясно о чем ты пишешь.

G>>Это в смысле IEnumerable не по массивам? Зачем его использовать в performance-critical коде?

EP>Затем что последовательности могут быть выражены разными структурами данных.
Не пойму о чем ты. Если у тебя массив или строка — пиши обычный цикл. Если там не массив и не строка, то пофиг — IEnumerable нормально работает.

EP>Собственно о том и речь — в C++ я могу накручивать уровни абстракций даже в performance-critical коде, без жёсткого penalty.

Это только если инлайнинг сработает. Об этом тебе и писали, дело не в языке, а в компиляторе. К сожалению для .NET негде такую оптимизацию производить.

G>>А IEnumerable (foreach) с массивами действительно тормозит (накладные расходы на Enumerator оказываются больше, чем затратры на тело цикла). Как раз из-за недостатка инлайнинга, в C++ foreach нилайнится.

EP>Так дело не в самом foreach — ты если распишешь его вручную, то он также будет тормозить, за счёт динамического полиморфизма..
Для обычных массивов jit оптимизирует foreach
var xs = new[] { 1, 2, 3 };
var s = 0;
foreach (var item in xs)
{
    s += item;    
}


выхлоп:
            var s = 0;
019A34D5  xor         esi,esi  
            foreach (var item in xs)
019A34D7  xor         ecx,ecx  
019A34D9  mov         edi,dword ptr [edx+4]  
019A34DC  test        edi,edi  
019A34DE  jle         019A34EB  

            foreach (var item in xs)
019A34E0  mov         eax,dword ptr [edx+ecx*4+8]  
            {
                s += item;    
019A34E4  add         esi,eax  
019A34E6  inc         ecx  
            foreach (var item in xs)
019A34E7  cmp         edi,ecx  
019A34E9  jg          019A34E0  
            }

Найди тут виртуальные вызовы.

Для не-массивов применяется оптимизация:
1) Реализация IEnumerator делается структурой
2) GetEnumerator возвращает структуру
3) foreach в этом случае не использует ни аллокаций, ни приведений к интерфейсу, ни полиморфизм


C IEnumerable другая проблема, которая связана с ФВП. Вообще ФП в C# довольно медленно работает, не создавался язык под него.

G>>Или ты имеешь ввиду использование ФВП для обхода массивов? Оно действительно и в C++, и в C# плохо работает. И в C++ и в C# такой код вручную оптимизируется.


EP>ФВП в том числе. А с чего ты взял что они в C++ плохо работают? Наоборот, прекрасно работают и отлично оптимизируются.

EP>Пример C++ -> JS vs C# как раз ФВП и использует.
За счет инлайнинга, который JIT не делает.
Но ты же не будешь в performance-critical на автоматический инлайнинг полагаться.

G>>>>Машинный код генерируется из IL. В нем все указанные тобой оптимизации делаются элементарно.

G>>>>Но у JIT нет столько времени на пребразования, как у компилятора C++.
EP>>>Что мешает сразу генерировать оптимизированный IL?
G>>IL — высокоуровневый язык. Он и так достаточно оптимален на своем уровне.

EP>И что из этого? C# версия без ФВП тоже компилируется в тот же самый "высокоуровневый IL", но работает быстрее. Версия с ФВП могла бы давать точно такой же IL.

Не могла бы, потому что делегаты. В F# отказались от делегатов, там лучше работает.

EP>>>Я выше привёл пример с трансляцией C++ -> JS. JS ещё "хуже" IL, но тем не менее он работает быстро.

G>>Что "хуже" ?
EP>Тем что JS более высокоуровневый.
И что?

G>>Работает быстро за счет "hotspot". Большинство движков JS перекомпилируют код на основании профиля использования. Кроме того "работает быстро" — это когда не используются ФВП.

EP>Вот именно, в исходном коде на C++ были ФВП и замыкание, в результирующем JS они были выоптимизированы компилятором C++, так как это элементарная операция (никакого динамического полиморфизма) — именно поэтому и быстро.
Ну так ты продолжаешь доказывать, что проблема в языке C#. А проблема в компиляторе, который ФВП не инлайнит. О чем я тебе и говорил с самого начала.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.