LINUX.ORG.RU

Продуктивность разработки на C++.

 , ,


6

12

Уважаемые программисты!

Предлагаю порассуждать о продуктивности разработки на C++ по сравнению с так называемыми скриптовыми языками. Вот, принято считать, что языки на вроде Python позволяют работать программисту более продуктивно по сравнению с C++. И что, дескать, на C++ надо писать только узкие места и всё такое.

Мне же хочется четкого понимания. Может быть это миф? А может быть это просто инерция, потому что так вот принято считать и все тут. Вот сегодня в C++ уже не надо думать об освобождении памяти, так как есть умные указатели. Сегодня есть уже более-менее нормальные IDE для C++. Так? Так.

Так что же тогда мешает писать на C++ столь же продуктивно, как на том же Python? Какие будут рассуждения? Может быть есть какие-то реальные обоснования на этот счёт, кроме как «в конторе Y так делают, значит смысл есть, они умные, им виднее». А может быть есть какие-то рецепты по продуктивности работы на C++?

Ответ на: комментарий от RazrFalcon

Первый раз вижу, чтобы кто-то хвалил плюсовые шаблоны. Тем более в сравнении с растом.

Так если плюсовые шаблоны невозможно перевести в растовские, так как плюсовые более мощные. Да, плюсовые возможно сильнее тормозят при компиляции и GCC для них выдаёт безумные портянки при ошибке компиляции, но они лучше работают.

Как на расте сделать тривиальное

template<class T>
int calc(T ptr_desc)
{
  return ptr_desc.base + ptr_desc.offset;
}
? Чтобы оно как и в C++ работало для любого класса, у которого есть числовые поля base и offset.

monk ★★★★★
()
Ответ на: комментарий от monk

Как на расте сделать тривиальное

Так же тривиально. Шаблоны рулят как раз там, где есть типы и их анализ. И в качестве тривиального надо было привести, например, function_traits.

anonymous
()
Ответ на: комментарий от azelipupenko

Не согласен. Должно быть Undefined.

NULL (в SQL), None и Undefined это одно и то же.

Ты находишься в пещере и хочешь покушать чего-то горячего. Но об огне ты ещё не знаешь, а горячего хочется, потому что холодно вокруг, пещера. И тут появляются пришлые люди, которые показывают тебе коробок спичек ... моя ЦНС торгаша здесь ищет решения, чтобы покушать.

Всё же чего хочется - покушать или горячего? Может быть этого не замечаешь, но твоя ЦНС прячет под рациональными мотивами иррациональные желания, т.е. покушать вполне рациональное желание, но не покушать горячего (называется рационализация).

... я никому и ничего не навязываю. Я всего лишь хочу есть мясо, а не жрать коренья ...

Именно что навязываешь и даже не заморачиваешься с маскировкой, может быть от неумения или непонимания как всё это выглядит со стороны. Вот выше ты навязал пещерному человеку утолять голод именно горячим и теперь навязываешь всем пакетный менеджер через его стандартизацию в инфраструктуре.

Вот и другие люди берут уже C++ и свои личные предпочтения пытаются сделать стандартными

Конечно, существует некоторое кол-во тебе подобных по образу мышления, но все так не делают. Обычно люди поступают иначе: решают локальные проблемы, без притязаний на общность, и предлагают свои методы другим. Если решения получают признание и множатся их рализации, то однажны решения становятся стандартом.

Это нормально.

Нет, это не нормально, но тем не менее почему так трудно признать что ты на самом деле ~фашист? Зачем все эти неумелые мимикрирования под либерализм.

... мне уж точно не по наслышке известно, насколько Emacs уступает коммерческим IDE для C++. То же самое и с Vim.

И тут у тебя точно такая же рационализация, о чём собственно я написал несколько последних комментариев о разнице между IDE и vim. С одной стороны хочешь заниматься разработкой, т.е. пожрать, но вместе с этим непременно хочешь горячего, т.е. IDE: мысль всё равно идет через горячее о каком инструменте не рассуждал бы.

Да, можно заниматься разработчкой с помощью IDE. Можно взять всякие эмаксы с вимами и неуспешно пытаться работать с ними как с IDE. А можно успешно работать с этими инструментами иным способом, не как обычно получается с IDE. И с последним ты точно не знаком, хоть и имеешь опыт работы с разными инструментами.

anonymous
()
Ответ на: комментарий от monk

Там трешовый синтаксис типов и шаблонов. Если в Си++ у шаблонов нормальная утиная типизация, то в Расте надо явно указать все поддерживаемые операции для всех шаблонных типов.

В rust это что-то типа концептов и в c++ так тоже скоро будет, опционально.

anonymous
()
Ответ на: комментарий от monk

Да, плюсовые возможно сильнее тормозят при компиляции и GCC для них выдаёт безумные портянки при ошибке компиляции

Это уже давно в прошлом. Оба основных компилятора, т.е. clang и gcc, теперь выдают умные портянки.

anonymous
()
Ответ на: комментарий от RazrFalcon

#![forbid(unsafe_code)]

И половина задач становятся нерешаемыми совсем. Начиная от простого двусвязного списка.

monk ★★★★★
()
Ответ на: комментарий от anonymous

Так же тривиально.

Приведи пример кода.

Шаблоны рулят как раз там, где есть типы и их анализ.

Шаблоны являются заменой сишному препроцессору и именно в этом смысле рулят. Позволяют автоматически инстанцировать код под типы, используемые в программе.

И в качестве тривиального надо было привести, например, function_traits.

Это в котором инстанцирование шаблона для каждого типа надо вручную делать?

monk ★★★★★
()
Ответ на: комментарий от RazrFalcon

Если под «лучше» вы подразумеваете использование шаблонов вместо макросов - то да, лучше.

Под лучше я понимаю автоматический вывод ограничения типов, а не ручное перечисление всех интерфейсов, необходимых для тела шаблона. Та же фигня и с трейтами. Например, делаю я шаблон в котором вызывается cmp. Вроде обязан использовать трейт Ord. А после этого выясняется, что я не могу сделать класс (структуру) и определить только cmp. Потому что Ord требует PartialOrd и Eq и я обязан реализовать ещё две ненужные функции. Как в Rust сделать шаблон, который работал бы на любом объекте, для которого определена функция cmp? Сделать ещё один трейт с одной функцией? Тогда не будет работать с типовым Ord.

monk ★★★★★
()
Ответ на: комментарий от anonymous

в c++ так тоже скоро будет, опционально

Когда опционально — хорошо. Когда единственный путь — для системного языка плохо.

monk ★★★★★
()
Ответ на: комментарий от monk

Шаблоны являются заменой сишному препроцессору

LOL.

anonymous
()
Ответ на: комментарий от monk

То есть вы предпочитаете разбирать огромные портянки, в попытках понять кто и где вызвал недопустимый шаблон, вместо нормальных ошибок?

Потому что Ord требует PartialOrd и Eq и я обязан реализовать ещё две ненужные функции.

Не понимаю. В C++ вам тоже придётся реализовать операторы сравнения. Только ошибка в случае его отсутствия будет занимать пол экрана.

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

То есть вы предпочитаете разбирать огромные портянки, в попытках понять кто и где вызвал недопустимый шаблон, вместо нормальных ошибок?

Что подразумевается под «нормальными ошибками»? Информативность ошибок, выдаваемых современными компиляторами, позволяет без особого труда относительно быстро разобраться с причиной. Лично мне почти всегда достаточно попасть в место ошибки и по контексту кода уже понять что же происходит. При этом информативности от сообщений на вроде «argument deduction failed» достаточно.

azelipupenko
() автор топика
Ответ на: комментарий от monk

Шаблоны являются заменой сишному препроцессору и именно в этом смысле рулят.

По факту - нет. Например, как сделать аналог макроса assert() на шаблонах без препроцессора? (Имеется в виду вывод имени файла и номера строки, где имеет место нарушение условия утверждения.)

azelipupenko
() автор топика
Ответ на: комментарий от anonymous

Всё же чего хочется - покушать или горячего?

Я с тобой согласен, что возможно питаться кормом, а не едой. Возможно жрать руками, а не употреблять пищу столовыми приборами. Возможно пердеть за столом, в том числи и в присутствии других хомо-сапиенс. Но как-то хочется горячего на вилочке, или между палочек, и чтобы под рукой была салфеточка, всё же :-)

Именно что навязываешь и даже не заморачиваешься с маскировкой

Это интересный анализ. Правда. Но вот что если сейчас именно ты мне навязываешь то, что я что-то кому-то навязываю?

Конечно, существует некоторое кол-во тебе подобных по образу мышления

Прям заинтриговал меня. А что такого особенного в образе мышления моем? Рационализация что-ли?

azelipupenko
() автор топика
Ответ на: комментарий от BceM_IIpuBeT

Зачем тогда Раст нужен?

Ничего личного, просто бизнес.

azelipupenko
() автор топика
Ответ на: комментарий от RazrFalcon

Вообще-то тут шаблоны ровном делом не при чем:

main.cpp:17:10: error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream}' and 'Data')

Компилятор тебе сходу сказал, что не так. Все остальное в тексте - это дополнительная информация в виде доступных вариантов использования operator<<.

anonymous
()
Ответ на: комментарий от slovazap

go — отстойная быдлоподелка хуже пхытона

Аргументы профессионала, чо

Судя по стилю - это Эдди. Нельзя серьезно воспринимать человека, программирующего микроконтроллеры.

tailgunner ★★★★★
()
Ответ на: комментарий от azelipupenko

По факту - нет. Например, как сделать аналог макроса assert() на шаблонах без препроцессора?

Я не имел в виду «полной заменой». Они позволяют заменять сишные макросы в большинстве случаев (аналог STL на препроцессоре тоже возможен, но на шаблонах им пользоваться гораздо легче).

monk ★★★★★
()
Ответ на: комментарий от monk

Зачем? Я воспользуюсь готовым. Я же не сишник, чтобы контейнеры писать.

PS:

Almost always it is better to use Vec or VecDeque instead of LinkedList. In general, array-based containers are faster, more memory efficient and make better use of CPU cache.

RazrFalcon ★★★★★
()
Последнее исправление: RazrFalcon (всего исправлений: 1)
Ответ на: комментарий от RazrFalcon

Ну так десяток строк мусора мне не нужны.

Так и не читай их, тебе заботливо подчеркнули красненьким то, что тебе лично нужно. Да и любая IDE тыкнет тебя в нужную строку и подсветит ее. Ну и тебе не нужны, другим нужны.

anonymous
()
Ответ на: комментарий от anonymous

Объясняю на пальцах: тут для примитивной ошибки простыня, а для чего-то серьезного сразу десяток страниц.

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

Almost always it is better to use Vec or VecDeque instead of LinkedList. In general, array-based containers are faster, more memory efficient and make better use of CPU cache.

Сходу:

https://doc.rust-lang.org/src/alloc/vec_deque.rs.html

Те же unsafe. И это нормально, Rust, если рассматривать его как замену С, просто обязан иметь много unsafe-блоков внутри безопасного кода.

anonymous
()
Ответ на: комментарий от RazrFalcon

Объясняю на пальцах: тут для примитивной ошибки простыня, а для чего-то серьезного сразу десяток страниц.

Нет, ты не объясняешь, а сливаешься. Во-первых ты уже облажался, «проблема» не в шаблонах, а в выборе функции для вызова, во-вторых для таких ситуаций размер сообщения зависит прежде всего от кол-ва вариантов, а не сложности, в-третьих это таки полезная информация. И если в Rust допустить похожую ошибку:

6 |     let path = Path::new(123);
  |                          ^^^ expected reference, found integral variable
  |
  = note: expected type `&_`
             found type `{integer}`
  = help: try with `&123`

то тебе выдадут не «простыню», а абсолютно бесполезный мусор.

anonymous
()
Ответ на: комментарий от RazrFalcon

Спасибо что открыли Америку! Оказывается раст использует unsafe в std, а люди и не знали.

Не просто в std, а для решения вполне себе алгоритмических задач, оторванных от ОС и железа.

anonymous
()
Ответ на: комментарий от RazrFalcon

Это каких таких задач?

Которые в std - та же дека, список и пр., если это было непонятно из контекста.

У меня почти 50к кода на расте, и ни одного unsafe (не считая биндингов).

На Java люди написали их миллиарды, причем многие даже представить не могут, зачем им нужен был бы unsafe.

anonymous
()
Ответ на: комментарий от anonymous

то тебе выдадут не «простыню», а абсолютно бесполезный мусор

Что тут непонятного? В гуглопереводчике забанили?

Вот вам шаблоны. У C++ без простыни, но и без смысла:

https://onlinegdb.com/SkOmh-q6W

vs

https://play.rust-lang.org/?gist=feeeb9a2bbf157175635753ebf82d91b&version...

RazrFalcon ★★★★★
()
Последнее исправление: RazrFalcon (всего исправлений: 1)
Ответ на: комментарий от RazrFalcon

Оказывается раст использует unsafe в std, а люди и не знали.

Так это же ты предлагал писать на Rust без unsafe и катался под столом когда тебе сообщили, что тогда в нём ничего работать не будет. Вот можешь прикинуть сколько от std останется, если запретить unsafe.

Поэтому пока Rust — это обрезанный С++ с возможностью местами писать безопасный код. Эдакие умные указатели на стероидах.

monk ★★★★★
()
Ответ на: комментарий от RazrFalcon

Вот вам шаблоны. У C++ без простыни, но и без смысла:

Вроде в обоих случаях написано одно и то же: для Index нет реализации для указанного типа.

monk ★★★★★
()
Ответ на: комментарий от monk

Суть в том, что весь unsafe уже написали и проверили. Осталось только его использовать, а не ходить по граблям, как в С/С++.

Поэтому пока Rust — это обрезанный С++ с возможностью местами писать безопасный код.

У вас очень странное представление о rust.

RazrFalcon ★★★★★
()
Ответ на: комментарий от monk

Я специально для вас процитирую:

error: no type named ‘type’ in ‘struct std::enable_if >’
vs
error: the trait `num::Integer` is not implemented for `&str`

Если вы считаете, что эти сообщение равнозначны по пониманию, то я удаляюсь.

RazrFalcon ★★★★★
()
Ответ на: комментарий от monk

Поэтому пока Rust — это обрезанный С++ с возможностью местами писать безопасный код. Эдакие умные указатели на стероидах.

Какое из этих трех утверждений описывает плохое качество?

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от RazrFalcon

Что тут не понятного. В гуглопереводчике забанили?

«help: try with `&123`» - гуглопереводчик превратит это в не мусор?

Вот вам шаблоны. У C++ без простыни, но и без смысла:

Это GCC под Rust косит, clang показывает на enable_if. Ну и тут надо было использовать:

static_assert(std::is_integral_v<T>, "RTFM");

enable_if не для таких задач. Ну и если говорить про дженерики в Rust, реши простую задачу

template<class T, int N>
struct IndexArray { 
    T items_[N] {};
};

template<class T, int N>
struct IndexVector { 
    std::vector<T> items_ {N};
};

template<class T, int N>
struct Index : conditional<N*sizeof(T)<4096 && is_integral_v<T>, IndexArray<T, N>, IndexVector<T, N>>::type {
};


int main() {
    Index<int, 20> idx1;
    Index<string, 2000> idx2;
}

Никаких enable_if, никаких дедукций, трансформаций, генераций, вариадиков, сверток и пр., что не доступно Rust. Просто выбор на основе аргументов. Это-то Rust может?

anonymous
()
Ответ на: комментарий от anonymous

template<class T, int N>
struct IndexArray {
T items_[N] {};
};

Индекс, который является массивом? Индекс в многомерном массиве?

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

«help: try with `&123`» - гуглопереводчик превратит это в не мусор?

Компилятор говорит, что нужно & добавить. Что тут сложного?

Ну и тут надо было использовать

Это простой пример. При использовании чего-то сложнее hello world простыня ошибок растёт экспоненциально.

Это-то Rust может?

Я такие извращения не пишу на обоих языка.

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

Компилятор говорит, что нужно & добавить. Что тут сложного?

Сложного ничего, только смысла в этом нет никакого и ошибку это не исправит. И если в С++ тебе выдается простыня с вариантами, то тут нет никаких намеков на то, что надо использовать, кроме того что это должна быть ссылка.

Я такие извращения не пишу на обоих языка.

И вот поэтому тебе не нужны unsafe в Rust, да и сам Rust.

anonymous
()
Ответ на: комментарий от anonymous

И вот поэтому тебе не нужны unsafe в Rust, да и сам Rust.

Неудачно выразился. Rust тебе нужен, и вероятно гораздо более чем С++, но в том числе потому, что тебе подошел бы любой достаточно продвинутый язык, в том числе с GC.

anonymous
()

Когда-то давно я думал, что все эти эксперты с лиспом и хацкелем были упороты, но я никогда так не ошибался. У этих экспертов сейчас появился раст и их упоротость взяла новые горизонты. И теперь я понимаю, что пусть лучше был бы хацкель.

rustonelove
()
Ответ на: комментарий от azelipupenko

но и в шаблонах чаще всего нет никакой магии. по факту, очень немного фич шаблонов, для которых пришлось менять компилятор. пожалуй, только variadic templates могу вспомнить навскидку. вот их не реализовать через макросы и остальные фичи. а остальное реализуемо через стандартный функционал языка и долгое время существовало в виде разных библиотек до того, как шаблоны были завезены. да, приходилось много писать руками, в шаблонах это это делает компилятор. но ничего такого прямо невозможного. вот если бы шаблоны можно было экспортировать - это совсем другой уровень был бы. а так, только генерилка кучи кода для ленивого программиста. и часто работает неоптимально.

Iron_Bug ★★★★★
()
Ответ на: комментарий от tailgunner

Какое из этих трех утверждений описывает плохое качество?

«Обрезанный C++». Проще работать на C++ с руководством по стилю. Тогда по крайней мере, когда потребуется сделать что-то нетривиальное, это можно будет сделать, а не страдать от того, что язык неполноценный. И бойлерплейта меньше.

Предыдущий Rust назывался Java. Её ведь тоже разрабатывали как системный язык. И возможностей безопасного кода гораздо больше, чем в Rust, и поддержка крупной корпорации. И похожие недостатки: многословность, отсутствие половины возможностей C++.

monk ★★★★★
()
Ответ на: комментарий от anonymous

Осталось чтобы мне ещё анонимы советовали на чём писать.

А уже писал, и не раз, что единственная причина, почему я пишу на C++ - это Qt.

RazrFalcon ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.