Здравствуйте, pagid, Вы писали:
S>>Надеюсь, в аду есть специальные котлы... P>Для нежелающих ускорять программу на 2% за счет её усложнения? Вряд ли
Для тех, кто "срать на оптимизации, всё равно (байтики медленнее передаюцца|юзер купит новый проц)".
И да, некоторым всегда сложно оптимизировать (странно, почему? )) ) и поэтому они называют этот процесс "усложнением".
Ну а некоторым банально лень. Эти ещо могут добавить "бизнес не платит".
Здравствуйте, Lexey, Вы писали: L>Какое в C управление памятью, кроме стековых и статических переменных и убогих malloc/free (и их аналогов)? В плюсах, да, уже гораздо лучше.
Я так понимаю, что речь идёт не об автоматическом управлении памятью, а как раз о ручном.
Ну, вот скажем, компилятор С++ за вас строит vtbl.
А если вы будете пилить ту же самую задачу на голом С, то ведь никто не может вам запретить навелосипедить ровно то же самое вручную — то есть в начало объекта вклеиваем указатель на метаданные, и поехали
int callVirtualGet(MyObject* object) { return object->vtbl->virtualGet(object) } // convenience function to avoid mixing up vtbl and data
Но! С и не связывает вас этой реализацией — к примеру, можно налудить компрессию vtbl для глубоких иерархий с широкими интерфейсами.
То есть вместо прикапывания номера слота в месте вызова, прикапываем идентификатор и идём вверх по дереву иерархий классов в поисках перегрузки (такая схема была реализована в delphi — при использовании для метода ключевого слова dynamic вместо virtual).
Ну, ладно, в С++ такое тоже можно налудить, и может даже получится чуть меньше бойлерплейта — за счёт шаблонов.
Тем не менее, вот он тот побитовый контроль, которого может не хватать на языках более высокого уровня.
Например, на том же C# (да и вообще любом CLR языке) невозможно написать свой класс "строка". Потому что он описывает объекты переменного размера с фиксированным заголовком, а в дотнете так нельзя.
Либо динамический размер однотипных элементов — массив; либо статический набор разнородных членов — структура.
В плюсах и C такая штука описывается как
struct stringHeader
{
vtable* vtbl; // we can skip explicit mention in C++ due to the included support for the virtual callsint m_size;
short data[0]; // here goes the dynamic part of string
}
На управляемом языке — нет, никак. Строки порождаются только через магию хоста. (Почти) всё управление памятью вынесено за сцену.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sheridan, Вы писали:
S>И да, некоторым всегда сложно оптимизировать (странно, почему? )) ) и поэтому они называют этот процесс "усложнением".
Потому как предыдущий оратор говорил о использовании шаблонов, как усложнении, и задал именно эту оценку полезности — ускорение на 2%
И да, изначально, разговор насколько понял, не о том, использовать ли шаблоны и этим упростить и немного ускорить программу, а о том стоит ли усложнять язык (включая компилятор, библиотеки и проч.) ради этих 2%
Здравствуйте, pagid, Вы писали:
S>>И да, некоторым всегда сложно оптимизировать (странно, почему? )) ) и поэтому они называют этот процесс "усложнением". P>Потому как предыдущий оратор говорил о использовании шаблонов, как усложнении, и задал именно эту оценку полезности — ускорение на 2%
Давай сразу уж не про шаблоны а про разработку проца и не про 2% а про 0.00002%
Ну чтобы даже тупому мне было понятно что овчинка не стоит выделки и вообще поэтому оптимизировать никогда не надо и вдобавок бизнес не платит.
P>И да, изначально, разговор насколько понял, не о том, использовать ли шаблоны и этим упростить и немного ускорить программу, а о том стоит ли усложнять язык (включая компилятор, библиотеки и проч.) ради этих 2%
Да, безусловно.
А дальше каждый сам за себя считает — будет ли ему сложно или нет.
Здравствуйте, Sheridan, Вы писали:
S>Здравствуйте, pagid, Вы писали: S>Давай сразу уж не про шаблоны а про разработку проца и не про 2% а про 0.00002% S>Ну чтобы даже тупому мне было понятно что овчинка не стоит выделки и вообще поэтому оптимизировать никогда не надо и вдобавок бизнес не платит.
Это ты уже сам написал. Оптимизировать программу добавлением сложных шаблонов(а некоторые еще и мув-семантику для этого везде лепят) совсем тупо. Нужно оптимизировать узкие места, алгоритм, выбирать соответствующие быстрые инструменты и архитектуру.
S>А дальше каждый сам за себя считает — будет ли ему сложно или нет.
Я видел вещи сложнее шаблонов, и в программирование и в других науках. И в код без злоупотребления фич последних стандартов проще добавлять другие оптимизации.
Не надо ипользовать шаблоны только чтобы убедить себя и других в собственном уме — это юношеский максимализм. Можно добавить более эффективные оптизации, при меньшем усложнении.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, Sheridan, Вы писали:
S>Здравствуйте, lpd, Вы писали:
S>Ну не умеете в шаблоны — делайте по другому
Я много чего не умею, как и все люди, например в крикет не играю. Но лучше не идти стадом за комитетом, придумавшим новые СТАНДАРТы и объявившим обычный С++03 устаревшим, а самому разобраться что они дают, и прикинуть какая польза от этого леса из угловых скобочек, от которого в глазах рябит.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, dsorokin, Вы писали:
_>>Чтобы сравниться с библиотеками алгоритмов C++, в языке претенденте должен присутствовать какой-то аналог механизма шаблонов (синтаксические макросы? Ещё что-то подобное? Не знаю...). Иначе алгоритмы будут или не универсальные (только под один тип данных) или же крайне не эффективные (там где в C++ будет просто сравнение двух чисел, в языках без шаблонов будет вызов виртуальной функции (или его аналог) со всеми печальными последствиями). D>Здесь выбор отвечающих этому требованию языков небольшой: C++, Rust, Ada. Может быть, есть еще что-то?
Вот из всех не маргинальных системных языков я не разбирался только с Ada. Так что к сожалению даже не могу прокомментировать подходит или нет. Поверю на слово. )
А так, ещё как минимум язык D позволяет полноценные шаблоны (причём одновременно мощнее и удобнее чем в C++).
Здравствуйте, lpd, Вы писали:
_>>Чтобы сравниться с библиотеками алгоритмов C++, в языке претенденте должен присутствовать какой-то аналог механизма шаблонов (синтаксические макросы? Ещё что-то подобное? Не знаю...). Иначе алгоритмы будут или не универсальные (только под один тип данных) или же крайне не эффективны lpd>Можно подумать у программистов других проблем нет, чем возиться с шаблонами ради 2% скорости программы. Тут по сети по десятки и сотни миллисекунд пакеты идут, а ты страдаешь из-за шаблонов. У нас не 1980 г. когда пытались все оптимизировать. Скоро в браузере будет все работать и требовать 128 ядер для чата, а ты все оптимизируешь универсальные алгоритмы. lpd>Такая оптимизация — не более чем предпочтение определенного типа программистов, а не реальная необходимость. Не говоря уже о том, что способов оптимизировать каждую программу обычно много и без шаблонов.
Я как раз ничего не оптимизирую, а просто использую стандартные готовые библиотеки. Осознавая при этом, что как раз из-за того, что они написаны с помощью шаблонов, они автоматически будут давать максимально оптимизированный код.
L>>>Какого лидера? C++ уже давно не лидер, а весьма нишевый язык. _>>Любой язык нишевый. lpd>Такие тезисы нужно доказывать. А если это невозможно(так и есть), то не разбрасываться ими.
Доказываю: приведи пример хоть одного языка программирования, который является лидером сразу во всех возможных областях. Отсутствие такого примера будет автоматических означать правоту моего тезиса.
lpd>Но вы будете до упора оптимизировать шаблоны С++, пока он не останется в нише языка для универсального сравнения интов и флоатов.
У C++ ниша не языка для сравнения интов, а ниша языка для написания инфраструктурного ПО. Ты вот прямо сейчас читаешь этот текст из браузера написанного на C++. ))) Более того, рантаймы всех остальных современных мейнстрим языков написаны на C++: JVM, CLR, CPython, V8 и т.д. Поэтому даже смешно говорить о сужение ниши C++ — она будет вечной основой всего IT мира.
Единственный сценарий, в котором C/C++ может перестать играть свою важнейшую роль в IT мире, это если появится такой же системный язык (достаточно низкоуровневый и быстродействующий), только удобнее. И вот как раз Rust претендует на эту роль. Но пока до реальных успехов ещё крайне далеко.
Здравствуйте, Lexey, Вы писали:
L>Собственно, я и хотел сказать, что никакого единого лидера нет. В разных нишах лидеры разные.
Конечно. Но в контексте сравнения именно C++ и Rust, изначальный тезис о попытках пиара Rust'а исключительно в виде критики текущего лидера выглядит вполне разумным.
L>ИМХО, он попадает в одну из ниш C++, но не во все. В тот же embedded он вряд ли серьезно зайдет в ближайшем будущем.
Ещё год назад помнится прямо на этом форуме кто-то писал, что перешёл на Rust при программирование STM32. Правда ему для этого пришлось руками написать кучу кода (который для плюсов уже есть в соответствующих библиотеках), но оно того стоило (ну по его словам ) ради более приятного языка.
V>Во-первых, C/C++ буквально созданы чтобы управлять памятью. Во-вторых, этот аргумент уже настолько надоел, что не могут придумать абсолютно ничего нового. Что думаете посадите своих программистов на Rust или C#, который рекламировали точно так же, и всё у вас будет в шоколаде.
У rust фактически такое же управление памяти как и у современного C++ то есть RAII и move. GC в нем нет.
V>Когда Бьерн Страуструп рекламировал C++ он говорил, что одно из его основных достоинств прямое управление памятью. И тут я, например, спрашиваю, какое преимущество у Rust? А мне в ответ C++ небезопасен, потому что позволяет управлять памятью. Нет, постойте ка, какое преимущества у Rust, я не хочу слышать про C++, говорите про Rust. Что там нельзя управлять памятью и это преимущество?
Там можно управлять памятью, разница с С++ только в том что компилятор жестко проверяет корректность этого управления.
Здравствуйте, Lexey, Вы писали:
L>ИМХО, он попадает в одну из ниш C++, но не во все. В тот же embedded он вряд ли серьезно зайдет в ближайшем будущем.
Чисто технически он лучше подходит для embedded чем С++. У С++ слишком жирный рантайм который
нельзя отключить не лишившись RTTI и\или исключений.
У rust все отключается проще и много библиотек поддерживают no_std.
Но все конечно решает инфраструктура, которая у rust пока слишком бедная для этой ниши.
Здравствуйте, lpd, Вы писали:
lpd>Это ты уже сам написал. Оптимизировать программу добавлением сложных шаблонов(а некоторые еще и мув-семантику для этого везде лепят) совсем тупо. Нужно оптимизировать узкие места, алгоритм, выбирать соответствующие быстрые инструменты и архитектуру.
Проблема только в том, что без шаблонов и прочих фич языка, у тебя получится сложнее, могу на примере пояснить — допустим у нас есть серверное приложение с пуллом потоков (довольно типичное серверное решение), ты передаешь в тред пулл функторы и они там исполняются, тоже довольно типичное решение.
Простой подход a-la С++03 — пишешь абстрактный класс Functor и наследуешь от него свои функторы, получается плоская иерархия из десятков классов, классы простые, т.к. реализуют метод — operator().
проблема 1 — тебе приходится создавать все в куче, т.к. виртуальные вызовы и прочая хурма, а значит управление памятью это проблема
проблема 2 — в свои реализации функтора ты передаешь параметры и они должны туда копироваться, а их много при этом, часто один функтор запускает следующий функтор, а тот запускает еще один и параметры передаются по цепочке (типичный паттерн в асинхронном программировании (в том же boost.asio), когда ты обрабатываешь прочитанные данные в первом коллбэке, отправляешь ответ и когда ответ отправлен запускается другой коллбэк, в котором ты делаешь что-нибудь и запускаешь чтение, по окончании которого снова вызывается первый коллбэк, примерно как здесь — https://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/example/cpp03/echo/async_tcp_echo_server.cpp, только в этом примере в коллбэки передается мало параметров, т.к. это эхо сервер, а в каком-нибудь более сложном приложении в коллбэки могут передаваться объекты потолще)
проблема 3 — внезапно тебе потребовалась поддержка cancellation и для этого тебе нужно добавить еще один метод в твой базовый класс и реализовать его в куче разных реализаций
Сложный подход — пишем шаблон — template <classs ... Args> class Functor; Используем type erasure для параметра конструктора, чтобы туда можно было передавать и указатели на ф-ии и лямбды и обычные функторы.
решение 1 — можно сделать оптимизацию для случая, когда параметры занимают мало места и размещать из не в динамической памяти, а в самом объекте Functor. Упрвление памятью не проблема, т.к. функтор реализует value семантику.
решение 2 — используем move семантику для параметров.
решение 3 — можно добавить реализацию cancel в одном месте.
Это конечно сложнее в реализации, но это IMO упрощает код. Подход Си с классами проще на первый взгляд, но это выливается в сложности в дальнейшем.
Здравствуйте, chaotic-kotik, Вы писали:
CK>решение 1 — можно сделать оптимизацию для случая, когда параметры занимают мало места и размещать из не в динамической памяти, а в самом объекте Functor. Упрвление памятью не проблема, т.к. функтор реализует value семантику. CK>решение 2 — используем move семантику для параметров.
Использовать move-семантику для оптимизации, особенно везде — это вообще дно. Оптимизировать нужно только узкие места программы. Передача аргументов не играет решающей роли в быстродействии. ЕСЛИ у тебя большие объекты копируются в критичном коде при легковесной обработке их, можно легко сделать только для них метод MoveObject(), а не перегружать язык новыми типами &&(имеющими только академический интерес) с запутанным синтаксисом.
CK>проблема 3 — внезапно тебе потребовалась поддержка cancellation и для этого тебе нужно добавить еще один метод в твой базовый класс и реализовать его в куче разных реализаций CK>решение 3 — можно добавить реализацию cancel в одном месте. CK>Это конечно сложнее в реализации, но это IMO упрощает код. Подход Си с классами проще на первый взгляд, но это выливается в сложности в дальнейшем.
По-моему можно обойтись виртуальными функциями и RTTI.
Да я и не против шаблонов самих по себе, какими они были в классическом С++. Я считаю тупиковым путь развития С++, потому что добавляются только представляющие узкий интерес только для специалистов языкам фичи, вместо добавления языку новых возможностей общего назначения. И на Java/C# уже давно пишется гораздо больше.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, lpd, Вы писали:
lpd>Использовать move-семантику для оптимизации, особенно везде — это вообще дно. Оптимизировать нужно только узкие места программы. Передача аргументов не играет решающей роли в быстродействии. ЕСЛИ у тебя большие объекты копируются в критичном коде при легковесной обработке их, можно легко сделать только для них метод MoveObject(), а не перегружать язык новыми типами &&(имеющими только академический интерес) с запутанным синтаксисом.
если у тебя достаточно простые обработчики, то передача параметров это узкое место, для серверов это зачастую так, я может пишу на каком-нибудь DPDK и у меня эти коллбэки миллионы раз в секунду вызываются, какие к черту RTTI с копированием?
про твой MoveObject не будет знать стандартная библиотека, соотв. многие оптимизации не смогут быть использованы
lpd>По-моему можно обойтись виртуальными функциями и RTTI.
можно обойтись, но код будет малоподдерживаемым и сложным, сложность будет не в шаблонах конечно, но в связях между 100500 объектами реализующими твой интерфейс, потому что у тебя один коллбэк будет зависеть от другого и иногда циклически, т.к. они друг друга вызывают, при этом это все будет не явно, т.к. ты будешь передавать туда не указатели на базовый класс
lpd>Да я и не против шаблонов самих по себе, какими они были в классическом С++. Я считаю тупиковым путь развития С++, потому что добавляются только представляющие узкий интерес только для специалистов языкам фичи, вместо добавления языку новых возможностей общего назначения. И на Java/C# уже давно пишется гораздо больше.
это странное представление, во всех проектах на С++ где я работал, шаблоны вполне себе использовались не академически
Здравствуйте, chaotic-kotik, Вы писали:
CK>Здравствуйте, lpd, Вы писали:
CK>если у тебя достаточно простые обработчики, то передача параметров это узкое место, для серверов это зачастую так, я может пишу на каком-нибудь DPDK и у меня эти коллбэки миллионы раз в секунду вызываются, какие к черту RTTI с копированием?
Все равно сомневаюсь, что копирование существенно влияет на быстродействие даже в таком проекте. Такое нужно измерять. И исключать копирование можно по-разному, указателями например.
CK>про твой MoveObject не будет знать стандартная библиотека, соотв. многие оптимизации не смогут быть использованы
Обычно можно работать вообще с указателями. Если очень-очень нужно, расположить объекты в памяти как угодно.
CK>это странное представление, во всех проектах на С++ где я работал, шаблоны вполне себе использовались не академически
Значит у вас "устаревший C с классами" и "сode smells", если не было многоэтажных шаблонов.
Это вопрос предпочтений, так нравится move-семантика — ок. Только назвали бы язык по-другому, а не С++, который превратили в сборище экзотических фич.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)