Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Здравствуйте, Serginio1, Вы писали:
S>> Еще раз С++ выигрывает за счет инлайнинга это известно всем. Шаблоны в отличие от дженериков по сути раскручиваются в исходный код с инлайнингом методов.
S>>Вот и вся магия. Это же раскручивание можно сделать и для дженериков. Большой то разницы нет.
EP>Вообще-то разница огромная.
EP>Например замыкания в C++ можно принимать в ФВП по конкретному типу, то есть без всякого динамического полиморфизма — такое элементарно инлайнится. А вот косвенные вызовы на объектах произвольного размера инлайнить на порядки труднее.
EP>Более того, инлайнинг это не единственный плюс относительно производительности — помимо этого например превалирующая value семантика.
Так и в C# тоже можно. Так же статически можно определить передаваемый тип. Другое дело, когда в динамике принимается интерфейс.
Отсутствие инлайна основная проблема. Для оптимизации никто не запрещает использовать структуры. Да проблема с массивами на стеке (в классе), но это уже мелочи.
S>> А насчет питона, то он уже стал статически типизированным?
EP>А он и не собирался
EP>Я говорю что если брать сферические рассуждения о гипотетической возможности оптимизировать код с тормозных языков до уровня C++ — то да, теоретически это вполне возможно, даже для динамически типизированных
Ну MS то собирается и делает определенные шаги.
S>>Но возможность приблизить скорость выполнения .Net код к C++ это просто небольшой плюсик не более, что бы убрать у С++ ников их главный козырь.
EP>1. Дело-то не в .NET, а в C# — сам язык, его семантика и идиомы не способствуют производительности.
EP>2. Приблизить, то есть убрать некоторые из тормозов — да, возможно. Но выйти на одинаковый — в обозримом будущем маловероятно.
EP>3. Производительность это не единственный козырь C++, помимо этого например кроссплатформенность, и гибкость языка.
EP> | | пример |
| | EP>Вот например, на Python можно сделать так (будет работать для любых типов имеющих соответствующие операторы):
EP>EP>def add(x, y):
EP> return x + y
EP>def sub(x, y):
EP> return x - y
EP>def apply(f, *args):
EP> return f(*args)
EP>print(apply(apply, apply, apply, add, 1, 2))
EP>print(apply(apply, apply, sub, 11, 2))
EP>
EP>Аналог на C++:
EP>EP>auto add = [](auto x, auto y)
EP>{
EP> return x + y;
EP>};
EP>auto sub = [](auto x, auto y)
EP>{
EP> return x - y;
EP>};
EP>auto apply = [](auto f, auto... args)
EP>{
EP> return f(args...);
EP>};
EP>print(apply(apply, apply, apply, add, 1, 2));
EP>print(apply(apply, apply, sub, 11, 2));
EP>
EP>На C# будет облом.
|
| | |
Это все шаблоны. В дженериках можно ввести ограничения. Дп будет не так красиво,
В C# нужно делать контракты, что то типа
T <T>add(T x, T y):where where T : IAdd
{ return x.add(y)}
Но во время компиляции при известном типе x.add(y) будут инлайняться.
Можно по аналогии с расширениями так же добавить аналог утиной типизации.
public static class <int>Extension:IAdd
{
int add(int y){this+y}
static int add(int x,y){x+y}
}
В С++ тебе все равно делать перегрузки для +,++ итд.
Аналогично можно сделать и для C#. Просто когда они озаботятся инлайнингом думаю появятся и новые конструкции.
Во всяком случае VladD2 еще на Видби показывал варианты и с инлайнингом где интерфейс реализовывался на структуре