Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, Serginio1, Вы писали:
EP>>>То есть ещё раз, код C# чисто по построению намного труднее оптимизировать — для оптимизаций до уровней аналогичных C++ нужно либо язык модифицировать, либо делать оптимизаторы намного более мощные чем оптимизаторы C++
S>> А можно поподробнее чем
S>>S>> T foo<T>(Func<T> f)
S>> {
S>> return f();
S>> }
S>>
S>>Принципиально отличается
S>>S>>template<typename F>
S>>auto foo(F f)
S>>{
S>> return f();
S>>}
S>>
EP>Тем что на C# после всех подстановок схематически получается:
EP>EP>class AbstractF
EP>{
EP>public:
EP> virtual int virtual_call() = 0;
EP>};
EP>int foo(AbstractF *f)
EP>{
EP> return f->virtual_call();
EP>}
EP>
А на C++:
EP>EP>struct ConcreteF
EP>{
EP> int x;
EP> int concrete_call()
EP> {
EP> return x;
EP> }
EP>};
EP>int foo(ConcreteF f)
EP>{
EP> return f.concrete_call();
EP>}
EP>
S>> И почему для C++ проще занматься оптимизацией?
EP>В этом примере — на C++ вызов конкретного метода, известен размер замыкания и стэковая аллокация. На C# виртуальный вызов, неизвестен размер замыкания и аллокация в куче.
EP>Виртуальный вызов и прочее можно соптимизировать, но это очевидно более сложная задача чем заинлайнить простой вызов конкретного метода
S>>T4 работают,
EP>Причём тут T4?
А при том, что можно сначала разворачивать исходный код дженериков в код на C# с инлайнингом по типу. Самый простой вариант.
Еще раз мы говорим не использовании дженериков из MSIL. А специализацию дженериков по переданному типу, лямды. Это можно сделать как на уровне исходников. Чем вобщем то и занимаются специализации шаблонов. Я много слышал, что в С++ хотели делать бинарную форму хранения. Что то подобное можно делать и для дженериков.
Я не вижу принципиальной разницы между шаблонами и дженериками. Наоборот дженерики даже проще, так как предоставляют ограничения.