Ads
Comments 412
На C++ ты пишешь код, который быстро работает.

Достаточно спорно, вернее это совсем не так. Подобные утверждения создают путаницу и только вредят C++, да и объективности как таковой. Правильно говорить, что на C++ ты можешь написать код, который быстро работает. А вот на дотнете не всегда. Дизайн языка/язык в общем виде, как и уровень его пользователей, определяют тот набор возможностей(и от языка, который даёт возможности. И от программиста, который хочет и может использовать). И уже это вкупе даёт ту самую производительность.

Если программист не знает как пользоваться возможностями, либо знает, а язык не позволяет — ничего не получится. И C++(современный) хоть и даёт практически безграничные возможности(относительно, конечно), но первую часть тезиса никто не отменял.

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

И это чистая правда. Причём это сложно донести не только людям со стороны, но и множеству программистов на самом C++.
мда… утверждать что Шарп лучше потому что на нём мордочки можно быстрее рисовать чем на тролтеховской куте и они красивее получаются… я в 2005-2010 гг. рисовал в борландовском билдере такие, что и сейчас не всегда получаются. с ворованными девелоперекспрессовскими компонентами, с наборами джедивцл, фастрепортом это было просто, быстро и красиво. но как можно приравнивать мордочки и качество языка?

Ну, честно говоря, если уж писать "наскоро" GUI на Qt, то я бы стал писать его на Qt Quick, а не на плюсовых виджетах, а к этому GUI на Qt Quick уже подключать какую-то "рабочую" логику уже на плюсах, благо делается это элементарно. У меня был небольшой опыт написания гуя и на C# (WPF+XAML), и мне Qt Quick понравился больше.

Ну, я про себя пишу. Для меня, например, вопрос возможности переиспользования одного и того же кода и на десктопе и на мобилках довольно важен. Qt мне такую возможность в значительной степени обеспечивает и на Windows, и на Linux с MacOS, и на почившем в бозе Windows Phone, и на Android с iOS. WPF — это только платформы MS, ну по крайней мере в свое время так было, может, сейчас с этим получше, но в одном из соседних обсуждений мне говорили, что лучше с этим не стало.

Какой-нибудь Xamarin для вас тоже не вариант?


P.S.Ну и по хорошему надо будет посмотреть что в плане кроссплатформа нам реально сможет дать .Net 5.0

Ну голый Xamarin, насколько я помню, это просто обёртка из классов поверх возможностей целевой платформы, то есть, условно, для Android будет один код, для iOS — другой. Xamarin Forms вроде как облегчает этот вопрос, но… только для Android, iOS и UWP, насколько я понимаю. Linux с MacOS в пролёте.

Ну если вы вот прямо под все ОС пишите, то тогда C# действительно менее удобен. Как минимум на данный момент уж точно.

Если говорить о кроссплатформенности, то корректно говорить о .NET Core, а он работает и на Linux, и на MacOS. Но стоит упомянуть что пока кроссплатформенный WPF Microsoft не завезли (только для Windows).
Но если сильно хочется всё таки иметь кроссплатформенный UI (Win, Linux, MacOS), на C#, да ещё и XAML-like синтаксисом формочек, то есть, уже какое-то время, AvaloniaUI.
А если хочется чтобы основная кодовая база была единой для всех платформ, что для .NET Core, что для Xamarin, то для этого прямая дорога в .NET Standard library. Пишите библиотеку, и можете её подключить и использовать в любой .NET среде — NET Framework, NET Core, Xamarin, Mono (а вместе с тем и Unity3D, который может работать хоть на консоли). Таким образом C#'ом можно покрыть практически все платформы (за исключением конечно же Embedded), при этом в моих руках всё удобство и гибкость С# и тд.

Мне как бы не особо интересно «написание библиотек», мне интересна такая разработка продукта, в процессе которой я мог бы переиспользовать как можно больше ВСЕГО кода продукта, в том числе UI (в идеале 100%) при переводе его с платформы на платформу. Авалонию я не пробовал, но вот здесь мне писали, что она очень сырая, да и поддержка мобильных платформ там, насколько я вижу, числится как экспериментальная.
Простите, а куда вы собственно пишете всю бизнес-логику без библиотек? Прям в main()? :)
Если говорить про переиспользование кода, то пишется всё под .NET Standard, и переиспользуйте где хотите. По UI, AvaloniaUI покрывает десктоп (один UI на все платформы), и Xamarin Forms покрывает мобильные платформы (опять же — один UI для Android, iOS, UWP).
В итоге мы имеем общий код, спокойно переиспользуемый на любой платформе, плюс переиспользуемый UI (отдельно для десктопа, отдельно для мобильных платформ).
Касательно авалонии в частности, то не видел чтобы её рассматривали для мобильных платформ ибо позиционируется этот фреймворк как замена WPF под .NET Core. И для мобильных платформ, как я уже упоминал, есть Xamarin Forms (один проект работает для всех платформ). Насчёт «сырости» я не хочу судить, так как проект в котором я его использовал, в плане UI, был довольно ненагруженный, и текущего уровня авалонии хватает за глаза — и графики построить, и рендерить картинки любой сложности, и при этом не задумываться про платформу на которой это всё собирается.
Мне честно даже очень интересно какие use-case'ы пока не может покрыть C#. Как уже говорилось это разработка под Embedded платформы (сюда же микроконтроллеры), и ещё High-Performance calculations. Есть ещё какие-то варианты?
Ну вот я ниже в качестве примера привел ссылку на продукт, который сейчас написан на C++ и Qt, и доступен под Windows, Linux, MacOS, под которые он собирается ну практически со 100% переиспользованием кодовой базы, ну и плюс имеет «облегченный» вариант для мобилок (Android, iOS) на тех же технологиях, которые тоже шарят между собой кодовую базу. Возможно, конечно, это у вас пойдет по графе «high performance calculations» (а их там есть, это да).
Интересный продукт, мы чем-то похожим в университете занимались, с моделями сердца работали и ещё какими-то органами (их срезы и модели в виде облаков точек).
Касательно тех критериев что вы описали в том комментарии, я считаю что это можно сделать на C#, и общую кодовую базу (.NET Standard), и UI хоть под десктоп и под мобилки (AvaloniUI + XamarinForms), при этом ни на шаг не уходя от C#.
Тут я вижу только 2 подводных камня:
1. HPC — а для предложенного вами приложения это, я считаю, самый критичный момент
2. Движок для рендера

Насчёт первого, я думаю бОльшую часть можно покрыть с использованием ILGPU (буквально веткой ниже пару слов написал об этом). Не думаю что можно абсолютно всё покрыть, всё таки в шарпе ещё не всё радужно с векторизацией как хотелось бы.
Для второй проблемы, есть два варианта. Это использование OpenGL(OpenTK) или любой другой плюсовой библиотеки для рендеринга, ну или честный .NET вариант (таких примеров правда не видел). То бишь данный момент нас так или иначе тянет к решениям на плюсах.
Либо, использование Unity3D в качестве UI. При этом данный вариант решает проблему как UI кроссплатформенности вообще (один 'UI' под все платформы), так и вычислений (используя Compute Shaders, который тоже в итоге кроссплатформенный и кроссжелезный).
Но боюсь что Unity не подходит для «кровавого enterprise'а», хотя если сильно захотеть…
Звучит такое решение конечно самоуверенно, да и я не знаю какие в вашем продукте есть подводные камни, какая архитектура и тд. Но если отвечать на вопрос что можно ли такое сделать на C#, я придерживаюсь мнения что да, это возможно.
Про ILGPU я прочел, да. Но, насколько я вижу, это CUDA only, а значит, только NVIDIA. Там, вроде, стоит красная галочка напротив AMD, но красная — это значит «когда-то в будущем». Ну и там не только и не столько рендеринг, сколько именно реально тяжелые вычисления при всяких там автоматических сегментациях, например, для чего и нужны собственно CUDA и OpenCL, а также при отсутствии нужных карточек это должно делаться и на CPU, причем как можно более эффективно. Не знаю, как у C# с этим. И насколько там будут эффективны compute shaders у unity — тоже вопрос. Ну ОК.
«А вот на дотнете не всегда.»
— и как выглядит это «не всегда», мне интересно?
У нас есть свой 3Д рендер, куча математики, процессинг высокополигональной геометрии и всё, таки, быстро работает. У мелко-мягких bing. Единственное где возникают проблемы это c gpu. Тут без плюсов пока сложно, а гибридайзером (или чем-то подобным) пользоваться не особо хочется.

А вообще, это глупый спор… всегда использовались параллельно и никто не страдал…
К слову о GPU на С# и необходимость в С++. Есть такая здоровская библиотека для .NET Core, называется ILGPU. Она позволяет писать код, прям на С#, который потом выполняется на GPU (либо на CPU если карта не поддерживается), при этом без использования С++ и без необходимости знать синтаксис шейдеров.
Конечно же, имеются ограничения и недочёты. Нельзя использовать ссылочные типы данных (ни классы, ни массивы), только структуры и встроенные в ILGPU типы. Последний раз когда я работал с этой библиотекой, там была поддержка только карт NVidia, ну и дебаг возможен был только при запуске кода на CPU либо танцы с бубнами в профилировщике от NVidia.
Так что стоит сказать что и в этом направлении C# двигается (хоть и силами скромного комьюнити).

P.S. очень уж порадовало то, что эта штука в итоге кроссплатформенная, и оооочень много времени сэкономило, так как данные были большие (гиперспектральные изображения на 5--700 МБ), и некоторые расчёты могли занимать 40 минут на CPU (против 3-4 секунд на GPU, и откуда взялся этот выигрыш в 600 раз я не осмелюсь объяснять).
Когда говорят о кроссплатформенности, то нет смысла рассматривать сферический язык в вакууме, потому что в современном мире мало кому нужен язык сам по себе, без фреймворков, библиотек и среды разработки.
Попробуйте-ка закодить, собрать и запустить бинарник с WPF-окошком, не выходя из Linux.
А то так и Objective-C можно считать кроссплатформенным, только за пределами Apple-платформ он неюзабелен.

Вы выбрали изначально не кроссплатформенный пример. Точно так же и на плюсах нельзя закодить какое-нибудь MFC-окошко, не выходя из Linux (что, имхо, не говорит в пользу MFC, но вряд ли годится в качестве аргумента против плюсов).


А давайте теперь рассмотрим кроссплатформенный пример. На плюсах мы возьмём портабельную технологию Qt, а на C# — портабельную технологию Avalonia. И… ну, у нас выйдет закодить бинарник с окошком, не выходя из Linux. С некоторыми приседаниями мы его тут же заодно скомпилируем под Windows и macOS.


Что дальше? Какие выводы можно сделать, и нужно ли их делать?

xamarin
avalonia ui
сейчас почти любой язык предложит целую кучу технологий
которые предложат кроссплатформенность во всех возможных сферах
Почему же тогда даже сама MS предпочитает писать кроссплатформенные приложения (Skype, Visual Code) на Electron? Наверное, с кроссплатформенностью .NET не всё так здорово?
С кроссплатформенностью GUI там всё совсем плохо. То есть формально окошки и кнопки можно сделать одной библиотекой, но товарного вида под всеми тремя системами (Win, Linux, Mac) добиться очень тяжело.
Насчет VSCode Eleсtron был обоснованным выбором, ибо прежде всего оно затачивалось под web разработку на js/ts. Eleсtron позволил быстро нарастить базу плагинов, так как стало просто интегрировать существующие инструменты из npm.
В том же sublime есть множество плагинов, которые являются лишь python оберткой над v8 для использования возможностей js библиотек.
Да и в целом VSCode работает достаточно шустро, пока не открывать в нем файлы с очень длинными строками.

Ну а Skype… Просто представим, что оно закрылось и больше не существует.
Да и в целом VSCode работает достаточно шустро, пока не открывать в нем файлы с очень длинными строками.

По моёму поверхностному взгляду, даже быстрее чем Sublime

Потому что сначала они разрабатывали вебовский редактор кода Monaco Editor для VS Online, а потом оказалось, что его можно упаковать в виде десктопного приложения...

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


При этом никто не мешает, ессно, и по городу ехать на механике и на гонке использовать затюненный автомат :)

Я в целом согласен с вашим комментарием, но думаю вот что.

Помимо описанных вами различий, есть ещё много нюансов вроде «сколько стоит ремонт разных коробок передач». И люди могут заранее о таких нюансах вообще не задумываться, а потом говорить «чёрт, для меня это приоритетно, знал бы — сделал бы другой выбор».

Поэтому на такие нюансы полезно проливать свет. А подобные споры как раз их и проливают: «вот сломается твоя автоматика — разоришься». Разумеется, из этого не следует «механика всегда лучше», но это ценная информация. И читать такие споры, по-моему, стоит не как «что лучше», а как полезную информацию о различиях.

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


Да, тот же Rust, а до Rust — ATS какой-нибудь.

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

Пример вам выше дан — вам осталось показать безопасность и «не медленнее». Хотя «не медленнее» вы уже показать не сможете, но хотя-бы безопасность покажите.

Для быстрой реализации сложных концепций ИМХО Ruby/Python предпочтительней — это я к тому, что в большом проекте и 2 языков мало

Анатолий: Мне кажется, что C# движется в сторону плюсов, он пытается отвоевать их рынок. А вот плюсы уже не движутся никуда.

Сергей: Откуда это? Что значит «плюсы не движутся никуда»?

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

Я еще ни разу не видел конструктивных бесед ЯзыкХ вс ЯзыкУ :)

Были такие беседы на моей памяти. Но в целом я не понимаю зачем ибо выбор языка должен исходить из условий стоящей задачи и доступных возможностей.

Да почему же. На мой взгляд это совсем не исключено и зависит скорее от того кто спорит.


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

Полезно ещё и знание, а на каком языке X сделан сам язык Y
Часть вопросов, тогда, сами отвалятся. :)
Это не значит вообще ничего. Да и в основном, языки написаны сами на себе. Условно компилятор Хаскеля написан на Хаскеле, и это спорно считается самой сложной программой, написанной на хаскеле:)

Неудивительно. Это на самом деле вообще один из самых сложных компиляторов, если не самый сложный.

Сергей на самом деле тоже имеет интересную позицию. То ему не нравится, когда есть компилтайм-надёжность («Я не хочу, чтобы моя программа что-то проверяла в compile time без моего ведома.»), то он считает, что модули существенно улучшат время компиляции (нет, не улучшат, время компиляции в современных плюсах идёт от шаблонов и constexpr-вычислений, а им модули не помогут никак).

Мне понравилось в графике расположение GO.
Довольно приятно расположен.
Дмитрий: Это очередная проблема. Есть у нас подход типа «модули». И я бы со своей колокольни сказал: ребята, мы переходим на модули и макросы больше не будут поддерживаться вообще никак. Более того, давайте со следующей версии, если включаешь модули, то отключаются макросы глобально везде. Вот это был бы мой подход. К сожалению, никто о таких кардинальных шагах не думает.

Сергей: Почему, о них думают. Но их не поддерживает комитет. Наверное, есть причины. Но я тебе предлагают сделать proposal. Это же открытое всё.

Дмитрий: Мы же понимаем, что это обречённый proposal. И обречён он по той причине, что никто не хочет внезапно сказать «надо переписывать»: допустим, в STL используются макросы, надо от них избавиться. Нужно, чтобы кто-то сделал волевое решение, сел и избавился от всех макросов.

Бгыгы. Объясняю почему не трогают макросы и почему proparsal обречён: Как мне подключить модуль хидер в зависимости от платформы под которую это собирается? Как мне генерировать в коде имена переменных и функций? Где статическая рефлексия? Вот поэтому комитет и не трогает макросы потому что много кода просто невозможно переписать без них. Да есть всякие сторонние генераторы, но макросы поддерживаются любым компилятором из коробки, а с утилитами могут быть сложности, что делает концепцию ущербной как на уровне «поддержки из коробки» так и с вопросами кроссплатформы.

P.S. «Магию» в Boost тоже стоит посмотреть ибо это фактически кусок STL feature или extented — как угодно можно назвать, но без Boost тяжко, а подключается он просто.
Как мне генерировать в коде имена переменных и функций? Где статическая рефлексия?

Всё это есть тут:
cppx.godbolt.org
Можно собрать себе среду.
Я попробовал, мне понравилось.
Бгыгы. Объясняю почему не трогают макросы и почему proparsal обречён: Как мне подключить модуль хидер в зависимости от платформы под которую это собирается?
Точно так же, как это делается в тех языках, где модулей нет. И если вам где-то не хватает метаданных, напомню что это одна из проблем, которые модули могут теоретически решить. Conditional compilation на базе модулей — это плохо, помимо всего прочего это превращает код в нечитаемую кашу из #ifdef-ов. То что люди привыкли так работать не значит что это хорошо.
Как мне генерировать в коде имена переменных и функций?
Вы сейчас снова жалуетесь на тот функционал который, помимо того что он нишевый, не решается только путем макросов. В C#, например, можно автоматически присвоить переменной значение, равное названию вызываемого метода. Это делается на уровне кода, а не на уровне макросов. То что метаданные еще не подвезли это просто еще одна проблема, которую нужно решать вместо того чтобы натягивать сову на глобус.
“Магию” в Boost тоже стоит посмотреть ибо это фактически кусок STL feature или extented — как угодно можно назвать, но без Boost тяжко, а подключается он просто.
Любая “магия” (например, использование Boost PP) плохо читается и понимается, что приводит к вполне очевидным maintenance costs.
Вы сейчас снова жалуетесь на тот функционал который, помимо того что он нишевый, не решается только путем макросов.

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

Ну да, всё так, а с учётом факта что в плюсы сейчас вливают успешно появившееся лет 10 назад, а кое что появилось и раньше, либо в других языках либо в куче внутренних pragma от компиляторов, то трогать макросы ещё долгов ближайшей перспективе никто не будет примерно с тем же определением это «мало кому и редко кому нужно, нишевая задача, уже работает везде одинаково, и т. д. и т. п.». Не знаю в чём уж совсем «ужас» макросов, с тем же успехом можно сказать что в регулярных выражениях тоже ведь «ужас». Макросы позволяют очень гибкую кодгенерацию из коробки, хоть и трудно поддерживаемую, но которую без полноценной рефлексии не сделать вообще никак.

Кстати говоря constexpr выражения уже кое где позволили заменить макросы нормальным кодом, это уже очень хорошо и это правильное движение.
> в плюсах сейчас занимаются вещами, которые должны были появиться 10 лет назад.

Я бы сказал 20 лет назад. Когда-то работал в ЦЕРНе, в команде ROOT (https://root.cern.ch/).
Уже тогда у нас был C++ интерпретатор, Reflection, всевозможные контейнеры, тесный контакт с Страустрапом. Уже тогда обсуждалось, как добавить все эти фичи в стандарт C++.
Но, воз и ныне там.
Сейчас для «низкоуровневого» программирования (видео, DirectShow, MF, COM, железки) пользую C++. Для всего остального — C#.
Мои любимые продукты DeExpress, Resharper.

Уже тогда у нас был C++ интерпретатор

То, что С++ нужно сейчас и просто «интерпретатор» — это разные вещи.

Reflection

Уровня «обойти поля пода»? Это тоже не то, что требуется от С++.

Уже тогда обсуждалось, как добавить все эти фичи в стандарт C++.

Да, но тогда это было позором. Эта была попытка напихать чего-то невнятного лишь бы напихать, но о чудо — комитет одумался.

Для С++ не подходят решения других языков, но не это главное — подобных решений нигде не было и нет. Где есть компилтайм-рефлексия? Да нигде, а где есть — там на уровне языка существуют одни поды(либо чуть-чуть больше). Откуда всё это брать?

За примерами далеко ходить ненужно. Достаточно посмотреть чем были концепты тогда, чем они являются сейчас. Я бы не хотел иметь то, что было раньше.

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

Тоже самое касается и рефлексии. Достаточно посмотреть на то, чем она была тогда(но уже тогда она была по-сути уникальной в своём роде. Даже в каком-нибудь D пошли по пути наименьшего сопротивления — сделали eval) и чем является сейчас. Лично мне и сейчас не нравится и противник ODR и всего, что с ним связано. В этом плане тот же шарп мне ближе.
Я не хочу троллить.
Свою миллионную линию кода на C++ я уже написал.
Тем не менее, последние 10 лет работы на C#, убеждают меня, что C# на 101% более продвинутый язык развитие которого не стоит на месте (в отличии от C++).
На пример, мне нравятся те фичи, которые появятся в C#8 (хотя сам «застрял» на 4.5 ).

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

Когда я говорил про «тесный контакт со Страустрапом» — это означает,
что были и продолжаются личные контакты, и Страустрап не раз приводил наш проект в качестве успешного проекта написанного на C++

Вот цитата из вики
"
ROOT разрабатывался как высокопроизводительная вычислительная библиотека, необходимая для обработки данных Большого Адронного Коллайдера, поток которых достигает нескольких петабайт в год. С 2009 года ROOT используется в подавляющем большинстве экспериментов физики высоких энергий; абсолютное большинство современных результатов и иллюстраций в этой области науки получено именно с использованием ROOT.

Включение в пакет интерпретатора C++ CINT значительно увеличило гибкость пакета, так как позволило использовать средства ROOT в интерактивном режиме или посредством написания скриптов, что сделало его похожим на MATLAB.
"
Более 10 лет назад комитет планировал ввести в стандарт C++, как интерпретатор, так и рефлексию.
Сам я когда-то написал apache module, который позволял исполнять C++ скрипты на серверной части. Что обеспечивало веб-интеграцию.
Именно по этому пути двигался C#.
+++
PowerShell — обеспечивает интеграцию C# с операционной системой.

С++ тоже на месте не стоит. Но да, я наверное соглашусь что особенно в последнее время Microsoft стал очень активно развивать С#. Как впрочем и другие свои языки/фреймворки и всю сопутствующую "инфраструктуру"/тулинг.

> Microsoft стал очень активно развивать С#

Когда-то я достаточно едко высказывался о Мише де Икаса, когда он начинал свой Mono, с GUI на основе Gtk++. Как я был не прав!

Но, именно Mono позволило портировать C# на Linux, iOS, Android.
Но да, я наверное соглашусь что особенно в последнее время Microsoft стал очень активно развивать С#

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

Это не то, что нужно как-то выделять. В целом, возможно поэтому вам непонятно развитие С++(и как следствие современный С++).

Тем не менее, последние 10 лет работы на C#, убеждают меня, что C# на 101% более продвинутый язык развитие которого не стоит на месте (в отличии от C++).

Напихать сахара и рантайм-фичей ничего не стоит. С++ подобным не занимается. И далее какие-то странные тезисы без какой-либо аргументации.

На пример, мне нравятся те фичи, которые появятся в C#8 (хотя сам «застрял» на 4.5 ).

Типичное «хорошо там, где нас нет».

Когда я говорил про «тесный контакт со Страустрапом» — это означает,
что были и продолжаются личные контакты, и Страустрап не раз приводил наш проект в качестве успешного проекта написанного на C++

Из этого ничего не следует. Строуструп не священная корова и никогда кем-то, кто занимается С++ на фундаментальном уровне не являлся. Он всегда занимался популяризацией и доступностью С++, а не какими-либо теоретическими, либо практическими изысканиями.

И сейчас Строуструп работает именно на тем, что-бы искоренить подобное вашим представление. Которые где-то когда-то что-то писали на C++, которые лишь номинально являются С++, а реально си с классами.

C++ после 0x фундаментально изменился и всё, что вы знали до — уже ничего не значит. Весь ваш опыт до — уже ничего не значит. И core guidelines призваны изжить этот опыт, вынести его за рамки С++ и никогда не называть это C++, дабы не обманывать ни себя, ни других.

Включение в пакет интерпретатора C++ CINT значительно увеличило гибкость пакета, так как позволило использовать средства ROOT в интерактивном режиме или посредством написания скриптов, что сделало его похожим на MATLAB.

Это так же ничего не значит. Это попытка дать студентом очередной питон. Это не какое-то фундаментальное направление С++. К тому же, сама реализация подобного достаточно тривиальна на фоне того, что разрабатывается для С++ сейчас.

Более 10 лет назад комитет планировал ввести в стандарт C++, как интерпретатор, так и рефлексию.

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

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

Задача статического языка прежде всего обеспечить фундаментальное свойство статики «собралось — работает». Это не питон и тут подобные проблемы не должны решаться реплом.

Что обеспечивало веб-интеграцию.
Именно по этому пути двигался C#.

Я не знаю каким образом скрипты дают какую-то веб-интеграцию и что это значит, но это так же не приоритетное направление С++.

PowerShell — обеспечивает интеграцию C# с операционной системой.

И что это должно значить? Лично меня не интересует ни эта «операционная система», ни какая-то интеграция в ней. Моё отношение к сему — есть ваше отношение к С++(вернее к тому, что вы неправильным образом называете С++).
мой последний комментарий втему

> Интерпретатор достаточно примитивная вещь, которая мало кому нужна.

Это не примитивная вещь.
Когда четверть века назад Masaharu Goto (мой друг Маса) решил написать C++ интерпретратор (CINT), все в один голос уверяли, что это невозможно сделать.
А, он сделал. Конечно, за это время была проделана большая теоретическая работа по алгоритмам написания интерпретатора и сейчас это сделать гораздо проще.

Если бы 20 лет назад приняли C++ интерпретратор,
то все эти питоны, баши, пых-пыхи, пёрлы оказались в мусорной корзине истории.
Все заменил бы C++

Это именно тот путь (единый язык для любой задачи, везде C#) по которому пошли мелко-мягкие, и несомненно, это позволило им сделать прорыв в технологии программирования.
Не видеть этого может только человек страдающий когниктивным диссонансом.

> Рефлексии нигде нет и никто не знает как она должна выглядеть для вводных С++

Именно благодаря «рефлексии» был пойман Бизон Хиггинса, заполнена самая большая база данных в мире. Я имею ввиду данные с Большого Адронного Коллайдера. Это, так называемый, ROOT data format, который на 101% основан на «рефлексии».

++
Хочу добавить последние 2 копейки…

Когда один из «экспертов» говорит

«Я тут хотел уточнить. Я про C# мало знаю, сам трогал его очень давно, в самых первых версиях»

дискуссию на этом можно было бы и закончить!

По поводу КДПВ: лучше бы взяли Саб-Зиро и Рейна из Ultimate Mortal Kombat 3, и тогда не пришлось бы перекрашивать Скорпиона.


Ultimate Mortal Kombat 3: Rain vs. Sub-Zero
Да, мы сами это в рабочей переписке сегодня обсуждали, но к тому моменту пост уже был готов :)


Для меня немного странная постановка вопроса и немного странная дискуссия. Сам в своё время начинал на С/С++, а потом всё больше и больше ушёл в С#. И для меня это просто немного разные "инструменты".
И сравнивать их это как сравнивать ну скажем топор и молоток. Вроде в чём-то похожие и местами один может худо-бедно заменить другой, но на мой взгляд не особо логично пытаться выяснить кто из них "лучше".

Молотком можно только отбить палец. А топором обрубить себе процесс в продакшне.
Анатолий: Мне, кстати, недавно попалась отличная статейка, где автор на разных языках (около 10) написал низкоуровневый драйвер — network driver для 10-гигабитной карточки Intel. От C до Swift, JS, Python и, естественно, C#. Если мы посмотрим на эти графики, которые у него получились, то C# на больших батчах (когда нивелируются расходы на запуск) идёт вровень с C и Rust.

Ну вот зачем упоминать этот позор. Как можно называть её отличной? Как можно говорить:

Если мы посмотрим на эти графики, которые у него получились, то C# на больших батчах (когда нивелируются расходы на запуск) идёт вровень с C и Rust.


Если кратко — это очередной ахренительный бенчмарк типа этой нетленки. Время идёт, а люди так и бенчат ffi на больших батчах. И ладно если первое имеет какой-то смысл(правда это нужно заявлять сразу, что мы бенчим именно ffi), то второе — это уже дно. Большие батчи нужны для уменьшения влияния ffi, но какой смысл бенчить ffi и при этом уменьшать его влияние? Какой смысл от быстрого ffi, если производится 1000 вызовов в секунду? Никто не знает.

Нужно сразу пресекать подобные заявления. А особенно неверные выводы из них. Несколько базовых тезисов:

1) Никто никакие драйвера не писал. Есть некое api, которые всё делает и железка его «поддерживает» — это api может получать данные из железки. Есть другое api, при помощи которого можно писать данные в определённое место, а далее само ядро всё разрулит. Т.е. вся логика драйвера существует в ядре, написана на си. Этот же «драйвер» просто конфигуратор + memcpy.

2) Почему-то во всех подобных бенчмарках за кадром остаётся самое важное? Что вообще в коде на разных языках происходит? Что там вообще выполняется? Как это выглядит.

За примером далеком ходить ненужно — достаточно взять упомянутый rust. Из тысячи строк на си — там получилось в 10(если не больше) раз больше кода. Почти весь этот код — unsafe-блоки с ffi к си. Где, собственно, rust и какой-то драйвер? Где та самая выразительность? Ради чего мы сменили шило на мыло?

3) Неверная идентификация проблемы. Правильные результаты там показывает именно начало графика. Проблемы C# обусловлены ни какой-то неведомой «когда нивелируются расходы на запуск» глупость, а вполне очевидными вещами.

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

Соответственно, всё сразу становится на свои места. Чем больший кусок данных мы пробрасываем через шарп/раст/го — тем меньше раз мы обращаемся к ним и тем меньше мы теряем на оверхеде. Т.е. по-сути чем правее — тем меньше шарпа/раста/го. А значит, что отсылка на правую часть графика — это призыв отказаться от шарпа/го/возможно и раста.

Возможно, в некоторых моментах вы и правы, но мне кажется критика теста не вполне обоснована.

Драйвер в первую очередь это софт, реализующий какой-либо стандартизированный интерфейс, для того чтобы ОС могла как-то унифицированно общаться с огромным зоопарком железячных устройств. Обычный фасад, у которого понятное определенной ОСи лицо, и вызовы железного API определенной железяки (чаще всего через прерывания либо другую командную шину) или API драйвера более низкого уровня (например Video BIOS) под капотом. И совсем не обязательно это должен быть код, который байты по одному шлет в LPT порт. Уже много лет как придумана и активно используется в драйверописании такая замечательная штука как DMA. Собственно, очень многие драйверы, включая драйверы дисков, звуковых, сетевых и видео карт, занимаются в основном именно тем, что вы описали, — конфигурируют DMA буферы, напихивают в них данные и вызывают железячную команду «сделать хорошо». Поэтому пример который вы критикуете — драйвер в самом прямом понимании этого слова.

Линка над картинкой ведет на репу на гитхабе, где вполне можно почитать код и понять что делает та или иная реализация. И какие костыли использует — зачастую комментарии в коде или readme файлы явно указывают на них. В реализации на C# стек пакетов, все буферы (кроме DMA области) — менеджд код. Цикл обработки Tx/Rx, работа с PCI — тоже. Ясно, что полно unsafe (иначе невозможно работать с указателями в C#). Но в целом — вполне себе понятный C# код, без засилья маршаллинга, использования библиотек ядра и прочих грязных извращений.

Насчет размеров батчей и их влияния на производительность я бы тоже поспорил. С точки зрения драйвера, при большем размере батча нужно выделить больше буферов, создать больше дескрипторов и скопировать больше данных, но зато реже. И меньше PCI вызовов нужно делать чтобы передать то же самое количество пакетов. Так что повышение производительности с увеличением числа батчей свидетельствует лишь о дороговизне PCI вызовов, на что, собственно, и указывается в тексте статьи, поясняющей исследование. Причем судя по форме графика, вызовы PCI влияют на любую реализацию приблизительно одинаково, выходя к оптимуму на размере батча в 32-64 для всех языков. Так же ваша гипотеза плохо накладывается на тот факт, что дальнейшее увеличение числа батчей в итоге негативно сказывается на производительности (к сожалению, в оригинальной статье не указывается конкретное число, но я думаю, что эффект должен быть уже начиная с 1024, хотя может зависеть от железа).

Я согласен, что данный тест скорее показывает что на С#/Rust/Go/etc. можно писать драйвера с приемлемой производительностью. Так же, он позволяет грубо сравнить производительность тестируемых языков с C/C++ в определенном классе задач, типичном для С. Но в целом, все эти «20 мегапопугаев в секунду» в итоге ничего не говорят о языке и/или его применимости в задачах другого типа. Но в целом, да, тест приведен, возможно, не совсем к месту. Но от этого он сам не становится некорректным.
Собственно, очень многие драйверы, включая драйверы дисков, звуковых, сетевых и видео карт, занимаются в основном именно тем, что вы описали, — конфигурируют DMA буферы, напихивают в них данные и вызывают железячную команду «сделать хорошо». Поэтому пример который вы критикуете — драйвер в самом прямом понимании этого слова.

Нет. И даже тут множество проблем. Конфигурирует ядро, через ядерное api, данные пропихивает ядро, обрабатывает ядро, вызывается ядро через сишный рантайм, взывает команду ядро. Т.е. в ядре работа с подобного рода устройствами уже почти реализована и обобщена.

Когда кто-то имеет ввиду драйверы — имеют ввиду именно драйверы. Драйверы в целом. Не «давайте из юзерспейса повызываем си через ffi». К тому же, даже это не всегда работает. Хотя казалось бы — что там может так сливать, но вот оно — может.

В реализации на C# стек пакетов, все буферы (кроме DMA области) — менеджд код.

От того оно и сливает. По поводу работы с памятью — она там явно не та, которая используется обычно.

Цикл обработки Tx/Rx, работа с PCI — тоже.

Там никакой логики нет, там всё примитивно — один шарповый синтаксический мусор и value-типы. Но даже тут оно умудряется сливать.

Какой смысл в шарпе? Что-бы написать «как на си», но при этом хуже чем на си? Если даже в таком явно подложном кейсе такие проблемы — что же там будет, если попробовать реализовать что-то действительно сложное.

Ясно, что полно unsafe (иначе невозможно работать с указателями в C#). Но в целом — вполне себе понятный C# код, без засилья маршаллинга, использования библиотек ядра и прочих грязных извращений.

А что же такое /sys, хотя это не библиотека да, но api ядра. К тому же, как я уже говорил выше — это не понятный C# код. Это банальный си раздутый синтаксисом шарпа и содержащий всякие заморочки.

Я не понимаю вашу логику. Какой смысл брать шарп и писать «как на си»? Это имеет какой-то сакральный смысл? Я этого никогда не понимал. Для людей из мира си — подобные вещи привычны, подобная работа с памятью привычна, подобные api привычны. Что мы получаем используя шарп? Мы получаем выразительность? Нет. Мы уходим от каких-то проблем? Нет — мы их создаём. Мы используем шарп в привычном виде? Нет. Мы получаем тот же результат? Нет. Что мы получаем?

Насчет размеров батчей и их влияния на производительность я бы тоже поспорил. С точки зрения драйвера, при большем размере батча нужно выделить больше буферов, создать больше дескрипторов и скопировать больше данных, но зато реже. И меньше PCI вызовов нужно делать чтобы передать то же самое количество пакетов. Так что повышение производительности с увеличением числа батчей свидетельствует лишь о дороговизне PCI вызовов, на что, собственно, и указывается в тексте статьи, поясняющей исследование. Причем судя по форме графика, вызовы PCI влияют на любую реализацию приблизительно одинаково, выходя к оптимуму на размере батча в 32-64 для всех языков. Так же ваша гипотеза плохо накладывается на тот факт, что дальнейшее увеличение числа батчей в итоге негативно сказывается на производительности (к сожалению, в оригинальной статье не указывается конкретное число, но я думаю, что эффект должен быть уже начиная с 1024, хотя может зависеть от железа).

Я не понимаю к чему вы и зачем это пишите? Вы нигде не опровергли мою гипотезу — только подтвердили её.

Очевидно, что на любых вызовах есть оверхед. Каким образом наличие оверхеда снизу что-то говорит об оверхеде сверху? Зачем вы пытаетесь манипулировать? К тому же, вы зачем-то пытаетесь меня обмануть.

Си выходит на максимум ещё на 8-16, когда как шарп не выходит никогда. Куда-то он выходит — только 128-256, но даже тут оверхед есть. То, что «другие языки» так же растут — это так же очевидно. Оверхед на ffi и на саму логику языков размазываются по батчу.

По поводу «эффект должен быть» — это глупость. Как мы уже выяснили — существует две компоненты. Компонента снизу и сверху, ведь си точно так же растёт и оверхед там тоже есть, как и есть он железе. таким образом ничего не мешает это компоненте снизу начать проявлять себя и снижать производительность. Когда как компонента сверху может уже либо совсем не влиять, либо влиять меньше. К тому же — наличие эффекта не означает, что он одинаково влияет на все языки.

К тому же, размер батча увеличивает летенси и где-то это может критично.

Я согласен, что данный тест скорее показывает что на С#/Rust/Go/etc. можно писать драйвера с приемлемой производительностью.

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

К тому же, раст в данном случае лучше вообще не упоминать. Там всё очень плохо в этой реализации. Если версию на шарпе ещё можно с натяжкой назвать «версией на шарпе», то вас про раст так не сказать. Го я не смотрел, но меня не особо го/шарп интересуют.

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

Не позволяет. Это фейковый бенчмарк, который ничего не бенчит. К тому же, вы только что поймали себя в ловушку. Если до этого тезиса вы могли бы говорить, что мои рассуждения об:

Когда кто-то имеет ввиду драйверы — имеют ввиду именно драйверы. Драйверы в целом. Не «давайте из юзерспейса повызываем си через ffi». К тому же, даже это не всегда работает. Хотя казалось бы — что там может так сливать, но вот оно — может.


Надуманы, но вы действительно сделали то, что я и говорил. Вы начали экстраполировать результаты этого позора на класс задач. Я не буду комментировать состоятельность этих заявлений — она попросту нулевая. Если даже в таком подложном бенчмарке, который ничего не бенчит и слить там попросту невозможно — вся тройка сливает — это полное фиаско.

Но в целом, все эти «20 мегапопугаев в секунду» в итоге ничего не говорят о языке и/или его применимости в задачах другого типа. Но в целом, да, тест приведен, возможно, не совсем к месту. Но от этого он сам не становится некорректным.

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

Во всех подобных бенчмарках надо чётко понимать — что мы бенчим и что выполняет основную работу. В конечном итоге, как я и сказал — этот бенчмарк бенчит ffi и сишный рантайм. Он не бенчит ничего иного. Хотя даже как бенчмарк ffi он плох. Он плох во всём.

Исходя из того насколько сильно его форсят, насколько удобные там результаты, насколько несостоятелен он сам по себе — я могу с достаточной долей уверенности предположить — возможно это целенаправленный вброс, либо попросту глупость. Но пусть будет глупость.

Я согласен, что данный тест скорее показывает что на С#/Rust/Go/etc. можно писать драйвера с приемлемой производительностью.


Насколько понимаю, драйвер должен работать в режиме kernel mode, а эти языки обеспечивают только user mode. То есть есть накладные расходы на переключение между режимами при каждом чихе. Чистый kernel mode возможен только на С и ассемблере. Даже С++ не может работать в этом режиме понормальному.

Rust и плюсы могут работать в чистом kernel mode, нужно лишь отключить фичи рантаймов.
Ну и учитывая специфику, не увлекаться шаблонами.

В каком-то ограниченном диапазоне могут. Еще вопрос — на какой платформе — Window или unix?

Вот прямо сейчас на redox-os. В остальных случаях особо тоже не вижу проблем фундаментальных.
А вообще, интересная идея в том, чтобы вообще не использовать кольца защиты и полагаться на изоляцию wasm рантайма.
В интернете где то лежит прототип такой оси.

Ну и учитывая специфику, не увлекаться шаблонами.

Это в смысле для снижения размера бинарника?

Не использовать кучу, например ;) А это значит, что, к примеру, std::string в драйвере уже нельзя использовать, но зато std::string_view можно.

По мне все эти споры больше дело вкуса. Мне допустим Java кажется намного логичнее C# из-за меньшего количества сущностей, и ничего не могу поделать.
Последние изменения стандарта C++, как мне кажется — попытки исправить проблемы которые привнесло метапрограммирование.
А ещё я на днях посмотрел пост про развитие стандарта C, прямо все больше и больше люблю С, очень стройный и логичный язык.
Вот ссылка, кому интересно.

Последние изменения стандарта C++, как мне кажется — попытки исправить проблемы которые привнесло метапрограммирование.

Странное заявление. Как можно исправить проблемы метапрограммирования добавив его ещё больше? Клин клином? Проблемой С++ было(и есть) малое кол-во метапрограммирования и малое ко-во фич. А так же, проблемой С++ является его изначальный дизайн со множеством скрытой семантики и откровенных дыр, но такой дизайн присущ всем ЯП.

А ещё я на днях посмотрел пост про развитие стандарта C, прямо все больше и больше люблю С, очень стройный и логичный язык.

Видео запоздало лет на 20. Всё это(и больше) всегда было в gnuc(который стандарт де-факто в мире си), откуда и перебралось в стандарт, причём почти всё перебралось ещё те самое 10-20 лет назад.

Как можно исправить проблемы метапрограммирования, добавив его ещё больше?

Сделав код проще и понятнее, пусть и за счёт усложнения самого языка.

Сделав код проще и понятнее, пусть и за счёт усложнения самого языка.

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

К тому же именно мета-программирование сделало из C++ то, чем он является и решило множество проблем везде и всюду. Тезис абсолютно некорректен. А то, что его можно упростить и улучшить — да, конечно. Но тезис всё равно некорректный.

хотя тезис уже спорный — где есть ещё более простое мета-программирование?

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


Кстати, именно в C++ мета-программирование называть простым у меня язык не поворачивается. Концептуально всё просто, но из-за большого количества подводных камней получается уже сложно.

Мне допустим Java кажется намного логичнее C# из-за меньшего количества сущностей, и ничего не могу поделать.


В java до сих пор нет checked arithmetics.
int foo = Integer.MAX_VALUE + 1; // тут должно быть исключение, а его нет. источник трудноуловимых отсроченных ошибок
Мне допустим Java кажется намного логичнее C# из-за меньшего количества сущностей, и ничего не могу поделать.

А мне Java не нравится из-за ограниченных языковых возможностей по сравнению с C#. Даже структур нет и полноценных дженериков.


Аналогично кому-то будет нравиться Go за простоту, а кому-то C++ — за возможности.

Я освоил Basic разлива УК-НЦ по максимуму, и я гарантирую, что это не лучший язык даже среди тру-бейсиков.

Та ладно таких веселых васиков больше нигде нет. Если в видеопамять по отрицательному адресу писать оно рисует отам вверху экрана, где типа верхней строки состояния. И убрать то что нарисовал никакими комадами clear и т.д. не уберешь. только ребут ну или опять же программно затереть. Информатичку чуть инфаркт не хватил когда она там логотип IBM увидела и убрать не шмогла.
Ага, Форт, тут и метапрограммирование и разделение синтаксиса и семантики и низко-высокоровневые слои применения языка, но увы слишком много отличий от майнстрима и корпоративного использования. :)

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

Под одну операционку это ныне замороженный (is done) .NET 4.8.


А актуальный .NET ныне — это Core 2.2/3.0 для бек-енд разработки, которую ведут обычно под Windows, но таргетируют как для Windows, так и для Linux.


И сейчас Core прямо выстрелил — после многих и многих лет застоя стартовало много бек-енд проектов на рынке.


Ну а с кроссплатформенной разработкой, похоже, в итоге не сложилось. И надо ли? Есть много других современных средств.

Можно писать на vscode под линуксами, но debuger придется от самсунга прикручивать, либо пользоваться проприетарным от микрософт в комплекте с vscode.

Rider под linux работает не намного хуже, чем под wndows. А в чем-то даже лучше.

Юзаю Core 2.3. Так вот, один из самых важных фреймворков — Entity Framework до сих пор до ума не допилен. Год назад, когда я на него перешёл, там не было GROUP BY (!), за год вот появилось, также как и конструкция IN. Но до сих пор нет UNION, какие-то проблемы были с DISTINCT (сейчас не вспомню что именно, но были). Про enity-sql и говорить не приходиться. Хотя непосредственно ASP .NET Core мне зашёл больше чем виндовс-онли ASP .NET MVC, благодаря многим улучшениям.
Уже лучше. EF Core 3.0 имеет еще более допиленный Change Tracker, Code First, и чуток лучший парсер Expression Tree, но это не значит лучший SQL. Использовать ли это в продакшине, хотя нет, использовать ли это для высоких нагрузок — решать вам.
В 3.0. так и не завезли пока union. Я-то кое-как выкртился, а вот в теме на гитхабе по union много тех, кто печалится от этого.
Как это не завезли??? Видать «конкуренты» до сих пор абстрактной «фигней» над абстрактным хранилищем страдают.
Для жаждущих пока только для 2.1, на след неделе докручу к 3.0, а то немножко там нарефакторили и надо легкий тюнинг — linq2db.EntityFrameworkCore
Редко меня можно удивить SQL запросом который я не могу на LINQ написать.
Мое мнение, что когда в запросах доходит дело до GROUP BY и прочие UNION, то в большинстве случаев я хочу дернуть хранимку чтобы быть уверенным, что оно работает как я хотел.

Лично я 2 года в продакшене использую EF Core и не было того, чтобы я сделать не смог. Не всегда элегантно, но работало. Плюс перформанс, если использовать AsNoTracking весьма хорош, по сравнению с обычным или упаси Боже, нхибернейтом.
Ну я всегда после написания чего-либо на LINQ проверяю через профилировщик (или как он там). Вспомнил, кстати, в чём проблема с DISTINCT. Конструкция типа: COUNT (DISTINC ...)… GROUP BY пока не преобразуется в SQL.
Может еще и оконные функции вспомним? И, думаю, никогда или не очень скоро будет поддерживаться. Разрабатывают EF Core очень квалифицированные специалисты, но к реальной разработке высоконагруженных систем, имеющие далекое отношение. По этому не удивляйтесь поставленным приоритетам.
Причем тут высокая нагрузка (особенно с Union, ага). Ни разу не видел, чтобы ОРМ использовали для высокой нагрузки. Для этого просто дергаем хранимку/вьюху из базы, где ее пишет DBD, а не EF с горы. Да, это гораздо медленнее в разработке, но когда я думаю про хайлоад, я подразумеваю, что деньги на ДБД и время на нормальную разработку есть.
Меня в целом устраивает Ef core, так или иначе получалось обойти все ограничения и добиться нужного без использования хранимок. Asnotraking, кстати, в моем случае прибавил не производительности, а снизил потребление оперативки (ну и оптимизация некоторых linq конструкций тоже резко снизила потребление оперативки).
Просто переход с классического EF на EF Core полтора года назад был достаточно неприятным (в классике активно использовался Entity SQL) и самым сложным моментом из всего перехода с ASP.NET MVC на ASP.NET MVC Core. А использовать классический EF на Core было как-то не красиво.
AsNotraking снижает потребление памяти в классических REST сценариях, когда по-сути, контекст живет только время обработки реквеста. Мы просто не кэшируем в памяти всю эту хрень.

А в чем были именно сложности перехода? Есть конечно костыли до сих пор, но особых сложностей я не видел.
Основная проблема была в том, что 3/4 запросов при переходе превратились в тыкву. Ну т.е. почти все запросы сложнее SELECT… JOIN… WHERE и UPDATE… WHERE. В итоге большинство хоть сколько-то сложных запросов вылились в SELECT * FROM tableName1 с последующей работой уже в памяти. В процессе переписывания обнаружилось, что на тот момент не поддерживался GROUP BY, что было вообще больно. К счастью, апдейт с GROUP BY пришёл довольно скоро, что упростило многие вещи. На старом EF запросы были написаны достаточно небрежно, благо он прожёвывал почти любые конструкции LINQ преобразуя их в SQL. Ну и при переходе на EF Core — пришлось всё заново осмысливать. Однако, это привело к ускорению этих запросов и меньшему потреблению памяти. Правда, через пол года были дополнительные действия по оптимизации расходов оперативки, включая тот самый AsNoTracking, приведение любых коллекций LINQ к ToList (это особенно много местами жрало памяти из-за многократных бессмысленных вычислений), добавлено кеширование всяких менюшек и прочих элементов, требующих частых одинаковых запросов. Но до сих пор ещё приложение при старте иногда, внезапно, съедает на 150мб памяти больше чем обычно (~400 мб вместо ~250 мб). Причину пока не установил, но где-то я явно напортачил.
  1. Пропал Model First подход. Это, конечно же, был наиболее неудобный из всех подходов, но переписать легаси всё равно не так просто.


  2. Пропали инструменты для автоматизации Database First — подхода.


  3. То, что раньше делалось через edmx, теперь надо делать через DbModelBuilder. Стало намного проще, но все старые костыли снова в мусорку.


  4. Entity SQL тоже пропал, запросы надо переписывать


  5. Довольно неудобно, что сам EF Core вроде как для .NET Standard написан, но вот для миграций нужен .NET Core и никак иначе.


Потому EF не может. Хранимки это и есть костыли. Шаг влево, шаг вправо — FromSql или хранимки. Выигрыш использования LINQ слегка пропал. Если в инструменте сплошные ограничения, я чувствую себя как на минном поле. Но ниче, потом так и рождаются сертифицированные специалисты — они знали, они плавали.

Это Вы из какого года нам пишете?
Сообщество очень активно участвует в разработке с 2014 года, причем изменения далеко не минорные. Например, привнесение платформенных SIMD в 3.0 сделано не разработчиком MS, насколько я знаю. И форки при таком подходе не нужны абсолютно, более того — они вредны.

У .NET есть куча ужасных косяков со скоростью в некоторых системных вещах.
Например получения и обработка всех файлов в директории.
На WinAPI эта часть может работать до 10 раз быстрее, чем на truъ .NET-е.
В итоге C++ CLI для таких задач лучше всего (боль маршалинья всех WinAPI на C# невыносима)
При этом если учесть что шарп это вооще не C а ява++ то все становится на свои места. Это не какой не С++++ а Simula-67++++.
Ну а если к этому присовокупить что GC полностью устарел по состоянию на конец 60-х потому что для ООП не дает вообще никакой автоматизации и в купе с неумением статической композиции и размещения временных объектов на стеке, полностью исключают многопоточность, превращая ее в эмуляцию однопотока на многоядерном проце, дженерики не позволяют определять алгебру над сущностями, модули паскалевского разлива не позволяют иметь несколько реализаций к одному заголовку и несколько заголовков к одной библиотеке…

Ну в общем сразу становится ясно почему С++ наиболее высокоуровневый язык на сегодняшний день. А то что быстрый и годен для системного уровня — ну так получилось.
Ну да. Очень давно. На конец 60-х стало отчетливо ясно что он полностью непригоден для ООП. А в начале 80-х во всех профессиональных ООП языках от него отказались в пользу более совершенной, гибкой и эффективной кастомизируемой автоматики управления жизненным циклом.
размещения временных объектов на стеке, полностью исключают многопоточность

Вообщето C# умеет размещать объекты на стеке правда только struct. И как это мешает многопоточности?
В стандартной библиотеке классы которой и используются в основном как временные каков процент оных struct?
А любой new при создании их на эмулированном общем стеке (это то что ошибочно называют кучей в шарпе) требует синхронизации доступа к указателю оного стека. Т.е. все потоки выстраиваются в очередь на каждом шагу.
При размещении же объектов на аппаратном стеке, который для каждого потока свой, такая синхронизация не требует. При этом в реалиях плюсов свою субкучу для каждого потока иметь — ну это вопрос зависящий только от необходимости такой субкучи для конкретной задачи, и вся автоматика управления жизненным циклом для такой субкучи продолжает работать в штатном режиме.
В отличии от шарпа где и с организацией субкучи поплясать с бубном придется и GC в ней работать точно не будет.
Ну да ведь в параллельных потоках обязательно нужно выделять новые объекты, нельзя же работать с существующими или использовать локфри пулы, или сотню других алгоритмов.
А любой new при создании их на эмулированном общем стеке (это то что ошибочно называют кучей в шарпе) требует синхронизации доступа к указателю оного стека.

хм… Интересно где вы подобное прочитали? Вообще вопрос выделения памяти в С# довольно таки сложный (хотя по вашему он простой и тупой как 5 копеек), они используют столько уловок, что выделение памяти в C# работает быстрее нежели родной и горячо любимый malloc, и я почему то более чем уверен, что аллокация в C# локфри, особенно если учитывать как легко пишутся лофри аллокаторы (из собственного опыта написания локфри аллокаторов)

И да, чуть не забыл, структурные переменные в C# которые на стеке создаются без new
что выделение памяти в C# работает быстрее нежели родной и горячо любимый malloc

Единичный new в шарпе иногда быстрее. Но только исключительно за счет гигантского отложенного оверхеда. При этом если учесть тот факт что вызовать new в плюсах надо в сотни раз реже чем в шарпе то как бы шарп в этом плане отстает в десятки раз. Это при том что глобальный new в плюсах не предназначен для создания мелких единичных объектов хотя и может для этого использоваться. В основном он используется для создания субкуч выделение из которых идет по оптимальному для обслуживаемой структуры данных алгоритму.
работает быстрее нежели родной и горячо любимый malloc

в синтетическом тесте который использует менее 50мб предвыделенной памяти для там нескольких тысяч распределений когда плюсы отгрызают эту память у оси постранично и с игнорированием того факта что в плюсах вместо эти нескольких тысяч вызовов new достаточно одного который выполняется в тысячи раз быстрее даже с отгрызанием памяти?
Ды нет, если не писать свой аллокатор для плюсов, то шарповый аллокатор всегда быстрее, за исключением может только больших кусков памяти.
Ну да ведь в параллельных потоках обязательно нужно выделять новые объекты, нельзя же работать с существующими или использовать локфри пулы, или сотню других алгоритмов.
ну к примеру вектора складывать, матрицы перемножать и т.д. и т.п. И промежуточные результаты таких операций как не крути а временные объекты.
Вообще вопрос выделения памяти в С# довольно таки сложный (хотя по вашему он простой и тупой как 5 копеек)

Да нет там никаких уловок. Просто смещается указатель на конец эмулированного стека. Поэтому сам new и быстрый всегда O(1), а у плюсов глобальный new O(1) только на полностью нефрагментированной куче, на фрагментрированной O (Log (n)) от количества свободных дыр. Но зато имеет постоянный гигантский оверхед по содержанию живых объектов, пропорциональный O(n) от живых объектов, в отличии от плюсов которые тратятся только на рождение и похороны, причем преимущественно массовые. Это уже не говоря про отложенный оверхед на абсолютно бесполезную в системе со страничной организацией виртуальной памяти дефрагментацию, без которой GC жить не может, и этого «быстрого» new тоже не будет.
Ох лол, и вы говорите это просто. Дефрагментация памяти, бесполезная, да вот только благодаря ей C# сильно обгоняет С++ в выделении памяти, а ещё делает вычисления более кэшфрендли.
Дефрагментация памяти, бесполезная, да вот только благодаря ей C# сильно обгоняет С++ в выделении памяти
Зато очень сильно отстает в хранении.
а ещё делает вычисления более кэшфрендли.

Этой байке уже реально 70 лет. Только не кеш френдли а минимизирует перемотку перфоленты. У вас ОЗУ до сих пор на перфоленте? Алииния кеша она как не крути 64 байта. А за ними промах.
Вы не понимаете о чём говорите, попишите высокопроизводительные программы и поймёте насколько велико значение кеша.

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

Само собой, я просто говорю, что его утверждения про то что кеш не имеет особого значение не соответствуют реальности.
что его утверждения про то что кеш не имеет особого значение не соответствуют реальности
Где то сказано что он не имеет значения? Сказано что дефрагментация тут не при чем вообще.
что аллокация в C# локфри, особенно если учитывать как легко пишутся лофри аллокаторы (из собственного опыта написания локфри аллокаторов)

Локфри она может быть только из разных субкуч/пулов а соответсвенно должен быть механизм явного назначения субкучи/пула потоку.
И как понимаю GC с объектами выделенными из этих пулов тоже не дружит?

У вас нет доступа к системным потокам из пользовательского кода.
Колбэки от ядра могут приходить только в пользовательские потоки.

Колбэки от ядра могут приходить только в пользовательские потоки.
Т.е. только через синхронизацию потоков. Толку тогда от этого эмулированного мультистека, если работа без синхронизации потоков не обеспечивается в принципе?

Это, если что, ограничение самой операционной системы, а не языка/фреймворка.

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

Неверно. Колбэки приходят в потоки, создаваемые пользовательским кодом.

Неверно. Колбэки приходят в потоки, создаваемые пользовательским кодом.

А вы их средствами чистого winapi когда нибудь вообще получали что так утверждаете? В главный поток окна они попадают совсем другим спсобом — подкапотный обработчик фреймверка в вызываемый в потоке api, записывает параметры вызова и отправляет их мессаджем. А уже поток обрабатывающий сообщения вызывает делегата.

Конечно, получал. И если вы почитаете документацию по функциям WinAPI, вызывающим колбэки, то там всё будет написано, что и где вызывается.


Вот, например:
https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfileex


Колбэк вызовется в текущем потоке, если он будет в alertable state — т.е. в состоянии Sleep/Wait.

Колбэк вызовется в текущем потоке, если он будет в alertable state — т.е. в состоянии Sleep/Wait.

Вообще то каллбеки ставят не для того чтобы их в слипе ждать. Особенно когда вопрос касается дуплексного сетевого ввода-вывода. При этом к примеру от той же WinHTTP каллбеки всегда в другом потоке приходят.
Вообще то каллбеки ставят не для того чтобы их в слипе ждать. Особенно когда вопрос касается дуплексного сетевого ввода-вывода.

А переключение контекста бесплатное, ага. То-то однопоточная асинхронщина показывает высокую эффективность под большой нагрузкой.


При этом к примеру от той же WinHTTP каллбеки всегда в другом потоке приходят.

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


А .NET перехватывает создание потоков через DLL_THREAD_ATTACH и корректно их инициализирует, чтобы пользователь мог не думать о CLR и GC вообще.

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

т.е. и 20 лет помучались и поняли таки что памятью надо управлять вручную, хотя это было доказано еще 50 лет назад?
Ну в общем если шарп до ума довести то однозначно плюсы получатся.
Интересно сколько времени у шарперов займет понять что кроме ручного управления памятью еще и автоматика управления жизненным циклом нужна, которая в плюсах уже лет сорок есть?
Не, это из С++ опыта, я просто плюсовик, С++ мой любимый язык, обожаю метапрограммирования и ненормальное программирование, C# на самом деле в работе не использую, но честно признаю (ибо сам тестил) что в C# выделение памяти работает намного быстрее стандартного малока.
автоматика управления жизненным циклом нужна, которая в плюсах уже лет сорок есть?

Вы про IDisposable чтоли который в C# очень очень давно появился?
Я про автоматическое управление жизненным циклом. Про автоматическую деинициализацию объекта при выходе его из скопа/деинициализации содержащего его объекта. Именно это позволяет кастомизируемо решать задачу автоматического управления как ресурсами/объектами так и взаимосвязями объектов. Память при этом рассматривается как вид ресурса.
GC этого не умеет от слова совсем. Да и задачу управления буферами памяти GC решает только в случае если задача управления взаимосвязями полностью решена. иначе течет косвенными утечками. Ручное же решение задачи управления взаимосвязями ничем не отличается от ручных вызовов delete и при этом делает GC абсолютно ненужным.
Структуры удаляются, у IDisposable вызывается dispose при выходе из using. Где нужно управлять ресурсами этого хватает за глаза.
Вообще то к примеру хэндл окна (даже упрятанный под кучу оберток) или видеопамять это такой же ресурс. Они у вас типа не разу не долгоживущими объектами каким то образом стали? А файлы? А косвенно владеемые ресурсы? из Dispose ручками высвобождаете? Зачем GC нужен если нужно все равно по дереву удаляемых проходить вручную всегда а то беда беда будет? И чем ручное написание using отличается от ручного вызова delete? Автоматика где?
И это вопросы не языка. Это вопросы обеспечения деинициализации объектов по правилам ООП, которые не зависят от языка. Абсолютно очевидно что GC абсолютно бесполезен для имплементации этих правил. Потому что предназначен для решения абсолютно противоположной задачи. При этом имплементация этих правил делает GC абсолютно ненужным, потому что аналогична вызову GC.Collect после каждого изменения ссылки, при этом гораздо эффективнее GC, поскольку не имеет постоянных накладных расходов на содержание живых, только на вынос мертвых который необходимо производить и при наличии GC.
Ваш бред в голове сложно комментировать.

Давайте сначала вы ответите на вопрос. Сколько кода в продакшн вы непосредственно написали и когда последний раз это было?
Ваш бред в голове сложно комментировать.
Когда вы крайний раз правила по которым ООП функциклит в голове освежали? Вы с ними вообще знакомы? А теорию графов изучали? А анализ графов взаимосвязей в вашей задаче когда призоводите до написания кода или после? А то вы похоже вообще просто не в теме что такое ООП и чем задачи управления памятью отличается от задачи управления жизненым циклом и задачи управления взаимосвязями.
Вы знаете, я код пишу в прод, а не читаю мистические правила времен советских вузов.
Вы знаете, я код пишу в прод, а не читаю мистические правила времен советских вузов.

Вообще то человек который анализирует задачу описывает ее в терминах той или иной методологии проектировани и потом реализует ее в коде называется инженер-программист.
А вот те которые академиев не кончали и сначала на клавиши жамкают те не код в продакшин пишут а баги быдлокодят.
На всякий случай, вы разговариваете с к.т.н. по 05.13.06.
Поэтому поверьте, я в программирование как теоретически, так и практически разбираюсь лучше вашего.

И поверьте человеку, который 14 лет пишет код в продакшн, а не блокчей очередной юзает: ваши представления о программировании лютейший ТРЭШ.
Поэтому поверьте, я в программирование как теоретически, так и практически разбираюсь лучше вашего.
От это крутые к.т.н пошли которые с моделью акторов не знакомы.
И поверьте человеку, который 14 лет пишет код в продакшн
т.е. до уровня проектирования системы по научным методика с последующей реализацией ее в коде даже за 14 лет не доросли? Вот потому вам и некогда — вынуждены постоянно обкостыливать грабли которые сами же и заложили.
Я не знаю что у вас за образование, и есть ли оно вообще, факт что читать вы так и не научились. Потому что вы оппонируете на какие-то вещи которые сами и придумали. А для .Net есть Akka, если уж вам так интересно.

В реальном мире системы проектируется не по научным методикам, а по бизнес методикам, потому что ЗП платит бизнес. Вы можете сказать бизнесу, что вы создаете гениальный фундаментальный фреймворк на Си, поэтому ваша задача будет решена через 5 лет. Но я уверен, что очень быстро вы отправитесь на мороз.

Спорить тут абсолютно бесполезно, потому что очевидно, что вы не разрабатывали софт для/в коммерческих компаний. Пока нет примеров ваших Гениальных проектов с научными методиками, спорить можно прекращать.
GC этого не умеет от слова совсем.

GC этого не должен уметь по определению. Память не является тем ресурсом, который должен быть обязательно освобождён по выходу из scope. А что должно быть освобождено обязательно — освобождается явно. Сейчас даже scope-based using добавили, чтобы сделать это ещё более удобным.


Я про автоматическое управление жизненным циклом. Про автоматическую деинициализацию объекта при выходе его из скопа/деинициализации содержащего его объекта.

При программировании многопоточных приложений на C++ я на практике сталкивался с ситуациями, когда подобное поведение оказывалось нежелательным, а управление памятью становилось весьма сложным и тяжёлым с нагромождением shared_ptr/weak_ptr и проблемами с циклическими зависимостями. В C# же такой проблемы нет.

а управление памятью становилось весьма сложным и тяжёлым с нагромождением shared_ptr/weak_ptr и проблемами с циклическими зависимостями.

ООП не пробовали использовать? В нем проблем с циклическими зависимостями нет.

А причём тут ООП? Ну вот есть два объекта, каждый из которых ссылается на другой. Они сами не удалятся.

А причём тут ООП? Ну вот есть два объекта, каждый из которых ссылается на другой. Они сами не удалятся.

Ну дак это уже нарушение правил предметной области. Т.е. сама такая ситуация это уже баг. Потому что деинициализация объектов в таком случае не может быть произведена вовремя. Поэтому правила построения связей такую ситуацию полностью исключают.
В ООП нет понятия нужен/не нужен. Есть понятие может/не может продолжать существование. При этом одной из причин невозможности продолжать существование есть разрыв связи типа копозиция. Т.е. нет препятсвующих удалению. Есть ответсвенные за удаление которые удаляют вместе с собой объекты на которые ссылаются. И смена ответсвенного невозможна, он назначается при создании. А соответсвенно и образоваие такого кольца тоже. При разрыве внешней связи произойдет уничтожение обоих объектов.
Ну дак это уже нарушение правил предметной области. Т.е. сама такая ситуация это уже баг. Потому что деинициализация объектов в таком случае не может быть произведена вовремя. Поэтому правила построения связей такую ситуацию полностью исключают.

Извините меня но что за чушь вы тут несёте? Два обьекта с ссылками друг на друга встречаются в любом ООП языке сплошь и рядом и никаким багом не являются.
Да возьмите любое банальное parent<->сhild отношение и вот вам уже пример такой пары.

Извините меня но что за чушь вы тут несёте?
То просто вы не въехали в суть того как это работает в ООП. чилд композирован в парента. т.е он не может существовать без парента. Разрыв этой ссылки приводит к мгновенному и перманентному уничтожению чилда. Кстати так о птичках это не циклическая а двунаправленная ссылка. И по сути в ООП все ссылки двунаправлены. И никакие счетчики не нужны.
Два обьекта с ссылками друг на друга встречаются в любом ООП языке сплошь и рядом и никаким багом не являются.

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

То просто вы не въехали в суть того как это работает в ООП. чилд композирован в парента. т.е он не может существовать без парента. Разрыв этой ссылки приводит к мгновенному и перманентному уничтожению чилда

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


Багом они станут если оторвутся.

Происходит сплошь и рядом. Вполне себе умышленно и тоже никаким багом не является…

И снова какой-то бред. У меня совершенно спокойно могут быть ещё и отдельные ссылки на пэрента и на чайлда. Но вот если я их уберу и оставлю только их ссылки на друг друга, то по вашей логике они навсегда останутся в памяти....
А теперь представьте что они все двунаправленные. Т.е. объект при уничтожении обнуляет/вычищает из контейнеров все оставшиеся на него ссылки.

То есть объект кто-то уничтожает вручную. Где же премущество автоматического управления ресурсами?

Ну вот поэтому то что с GС раньше или позже начинает течь как минимум ресурсами а то и косвенными утечками. Потому что объекты не деинициализируются как это предписывают делать правила ООП.

Опять какие-то ваши фантазии и абсолютное непонимание того как работает GC. GC в такой ситуации совершенно спокойно убирает оба объекта.

в такой ситуации совершенно спокойно убирает оба объекта.
GC уберет буфера памяти занимаемые объектами, а не объекты. Он вообще объектами не управляет, только буферами памяти. При этом вопрос наличия сторонней ссылки на объекты точно так же придется разруливать и при использовании GC, у которого при наличии такой дополнительной ссылки с альтернативной трассой на рут и происходит коственная утечка. Решается это опять же или ограниченым по функциональности частным случаем со слабыой ссылкой, либо общим случаем с двунаправленно связью с инстантным оповещением ссылающегося.
Т.е. вопрос с необходимостью в слабых ссылка опять же не из языка и способа управления памятью растет, а из правил ООП которые предусматриваю два типа связей — композицию и агрегацию. При этом поведение жестких ссылок с GC перевернуто по сравнению с композицией на 180 градусов, а несвоевременная и даже негарантированная деинициализация объектов и является причиной несоответсвия модели акторов, что и является причиной всех граблей. Имплементровать же в автоматическое поведение ссылок в соответствии с моделью акторов GC не может от слова совсем, в отличии от современной автоматики, потому что разрабатывался в 1959-ом и предназачнен для управления пассивными буферами памяти, а не активными моделями сущностей предметной области, которыми являются объекты в терминах ООП.

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

Память не является тем ресурсом, который должен быть обязательно освобождён по выходу из scope
А инстанс который живет в этой памяти должен быть деинициализирован обязательно. Опять же по правилам ООП. Поэтому придется по дереву удаляемых пройти все равно. И гораздо эффективней попутно и буфера в список неиспользуемых занести пока знаем какие, чтобы не сканировать постоянно всех живых.
А инстанс который живет в этой памяти должен быть деинициализирован обязательно

Совершенно не обязательно, если единственный используемый ресурс — это память.


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

Не факт. Удаление из глобальной кучи вотпрямщас дорогое + требуется межпоточная синхронизация.

Совершенно не обязательно, если единственный используемый ресурс — это память

А откуда вы знаете какой там ресурс под капотом и какая там вообще под ним глубина дерева композиции объектов и какие агрегации у этого поддерева нужно разорвать при деинициализации? В общем случае об этом знает только сам объект. Именно поэтому и требуется деинициализация всего удаляемого подерева.

Об этом говорит наличие интерфейса IDisposable и намерения программиста по явной очистке ресурсов.

Об этом говорит наличие интерфейса IDisposable
Так он у всех абстрактных базовых типов должен быть. Потому как абстрактный предок не может знать что будет под капотом у потомков. А обрабатывается то оный потомок по ссылке на предка.
и намерения программиста по явной очистке ресурсов

20-ый год 21-го века. А все ручками делать. В том числе Dispose писать. Не я с такими глупостями еще в прошлом тысячелетии покончил. намучался достаточно на паскакале. Т.е. никакой разницы с полным отсутствием автоматики GC не дает кроме ненужного оверхеда.
Dispose ничего общего с GC в общем случае не имеет, и в большинстве не системных классах используется для иных целей.
Dispose используют для очистки ресурсов только когда надо освобождать неуправляему память, например при работе напрямую с DLL.
Но в реальности (продакшене) это используется как обычный метод который будет вызываться в using, с помощью него можно писать, например, структурные логи.
using(Log.Header())
using(Log.Body())
Для managed ресурсов явное написание Dispose вообще не имеет смысла.
Только оно очень редкое. Особенно с учетом того что вся мелочь композирована статически, a объекты которые живут на куче вообще по определению долгоживущие.
Удаление из глобальной кучи вотпрямщас дорогое + требуется межпоточная синхронизация.
Но при этом эти затраты гарантированно единовременные и таких операций требуется на несколько порядков меньше. В отличии от GC, который дает огромный постоянный оверхед и остановки всех потоков, и при этом не обеспечивает корретного поведения объектов.
Про принцип суперпозиции который говорит о том что оптимальность элементов не гарантирует оптимальность комбинации? Вот современная автоматика и оптимизирует систему в целом, в отличии от GC в котором ускорение отдельных операций приводит к гигантскому оверхеду в целом.

GC не останавливает потоки. Он вообще может в фоне работать. Поэтому не приходится тратить ресурсы текущего потока на освобождение памяти.


Единственная возможная патологическая ситуация — когда GC не успевает за

GC не останавливает потоки. Он вообще может в фоне работать
В фоне != параллельно. Ану ка прикиньте алгоритм сканирования трассы на рут без остановки потока аппаратный стек и содержимое регистров CPU которого и является оным рутом.
А теперь прикиньте алгоритм дефрагментации без остановки потоков которые имееют доступ к перемещаемым буферам, особенно при условии того что точно знать какой поток может иметь доступ к какому объекту GC не может. Прикинуть то можно, только вот синхронизация потребуется очень нетривиальная и на каждый перемещаемый буфер.
Поэтому не приходится тратить ресурсы текущего потока на освобождение памяти.
У вас столько ядер что им заняться нечем? При этом бутылочное горлышко как сканера так и особенно дефрагментатора — скорость шины. Так что запускать его парллельно — это еще больший оверхед. Так что фоново это по сути сам отработает когда предвыделенный кусок памяти закончился.

Нет никакой проблемы с синхронизацией — она попросту не нужна, т.к. каждое поколение обрабатывается ровно одним потоком.

При программировании многопоточных приложений на C++ я на практике сталкивался с ситуациями, когда подобное поведение оказывалось нежелательным,

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

Программисты на Haskell, Clojure или F# смотрят на этот комментарий с недоумением.

Самое странное, что никак не представлен гймдев, где плюсы до сих пор на коне (и не надо мне расказывать про Unity, там на шарпе только логика пишется, движок всё равно на плюсах, а самая частая жалоба на игры на этом движке — тормозит на топовых конфигурациях).

В самом начале срача дискуссии кратко упоминалось — если вам надо быстро разрабатывать — это к шарпу, если вам надо чтобы разработанное быстро работало — это к плюсам. На текущий момент единственный плюс у C++ — это предсказуемое время выполнения, что в геймдеве критично (бюджет времени 16 мс на кадр).

Подробней про это можно посмотреть в серии лекций томских Unigin-овцев: www.youtube.com/playlist?list=PLgeSUiT3pydG7KchiEhjYvwkORh7TSGNi
А на самом то деле если вам надо чтобы разработать быстрее чем на шарпе и чтобы работало быстро — это опять же к плюсам с соответсвующими фреймверками. А причина срача она в том что Майкрософт подобные фреймверки не осилил. Даже WinForms — результат совместного проекта с Борландом, релизить который Борланд отказался, по причине крайней убогости полученного гибрида по сравнению с нативным предком.
Меня всегда умиляет фраза «язык мультиплатформенный» от разработчиков, которые использую интерпретируемые языки. Как-будто эта мультиплатформенность родилась сама собой.
Больная мозоль.
На работе лежит проект, сделанный аж на Builder C++5. Много форм и элементов, СУБД,fastreport и пр.
Надо его переписать, но не могу сделать выбор. Кроссплатформенность не нужна. Важное — нужен мощный генератор отчетов.
Нынешняя громила Embarcadero Builder пугает. Смотрю в сторону Qt — очень радует он меня, и размер distroDLL в принципе адекватен.
А вот к шарпу отношусь напряженно, отчасти из-за кучи фреймворков и страха совместимости между ними. Мой бинарный код от BCB5 отлично работает на всех Windows и будет работать дальше. А шарп настораживает.
У кого-нибудь был похожий выбор? Спасибо.

У Microsoft с относительно недавних пор появилась такая штука как .Net-Standard. И как раз для того чтобы решать проблемы совместимости.


Если совсем грубо, то если вы пишите ваш код в библиотеке совместимой с определённой версией .Net-Standard, то он работает на любом фреймворке, который поддерживает эту версию.

Мне кажется что для C# гораздо лучше для сравнения и холиваров подходит Java. Эти два языка имеют похожие парадигмы и идеи и рыночные ниши в которых конкурируют. Это два детища microsoft и oracle которые были созданы в одинаковых условиях конкурентной борьбы.

Но С++ был создан с другими целями, гораздо раньше у него своё мировоззрение и идиомы. С++ не похож на эти два языка. Но на нём можно писать код мало отличимый (благодаря zero cost abstraction и богатому функционалу) от многих других языков.
Идеализм этот с некоторыми от C++, «убрать макросы», ну come on. Как я без макросов организую себе удобоваримые properties в классах, например? Пофиксите мне язык, добавьте адекватные class properties чтобы без этого вот бесконечного .set_value (a.get_value () + b.get_value()), добавьте named orderless function arguments, чтобы я мог тренировать свою память где-нибудь ещё кроме как привязки аргумента к его имени «на глазок», и проводить вечера с семьёй, а не с перетасовыванием аргументов при рефакторинге — вот тогда поговорим о удалении макросов. А пока я это всё только макросами и могу более-менее организовать, чтобы писать линейный код, а не продираться сквозь завалы тривиального синтаксиса.
Я однажды узнал перевода слова get с английского языка. Теперь применять префикс get в методах получения значений морально сложно.
Приведу некоторые почти очевидные примеры:
man.get_married();
bank.get_money();

Во многих библиотеках (например Qt) трендово сейчас называть методы получения свойств так же как и свойство, что повышает читабельность программы особенно среди англоязычных программистов.

Пример с get_married() просто ужасен.
Уже давно все нормальные люди для bool проперти используют is вместо get.


Что лучше, gameObject.GetDisabled() или gameObject.IsDisabled() ?


ИМХО, 2 вариант гораздо лучше читается.

Для bool проперти is перфикс — отличный выбор, никто же не спорит. Но ведь это может быть и не булевская переменная, а обьект — ребро социального графа.

Речь о get VS noget.
А get_married() лишь яркий пример который на слуху у многих людей, что бы понять почему get для пропертей плох.

Для устранения путаницы должно быть так, ИМХО:


man.get_married(woman) — женить man на woman.
man.is_married() — женат ли man?
man.is_married(woman) — женат ли man на этой woman?
man.get_wife() — получить информацию о той woman, на которой женат этот man.


но с полноценными пропертями это переписывается красивее…
man.GetMarried(woman) — жениться
man.Wife — возвращает жену или null
man.IsMarried — возвращает man.Wife != null
man.IsMarried(woman) — возвращаеет man.Wife == woman


Для многоженства надо писать вариант с man.Wives, с возвратом массива\списка\иного IEnumerable, ну и в прочем учесть

UFO landed and left these words here

Вот я хотел это написать, но комментарий отредактировать не получилось.
Так-то стоит обоих наследовать от Person.

С целью, естественно, максимальной гибкости системы. Туда же и тему выше про многоженство\многомужество, в мире куча разных вариантов, и стоит поддерживать все, тем более, что это "почти бесплатно" с т.з. кода

Ну вот, кто-то и комменты минусанул, и анонимно в карму насрал, как положено… явно очень консервативно настроенный гражданин без чувства юмора.
UFO landed and left these words here
UFO landed and left these words here

Не на partner, а на spouse тогда уж.


И, кстати, толерантность тут ни при чём — с симметричными отношениями попросту проще работать.

man.get_married(woman) — женить man на woman.

Главное не тащить это в публичный интерфейс!

Однозначно, это должно быть личное решение экземпляра класса.
А то в некоторых странах этот метод вытащен в паблик, хоть и "наоборот".

> Во многих библиотеках (например Qt) трендово сейчас называть методы получения свойств так же как и свойство, что повышает читабельность программы особенно среди англоязычных программистов.

Yes. От безысходности. Но работал довольно давно с библиотекой, там .married() ещё возвращало ссылку на значение вместо поддержки тривиальных сеттеров, так что можно было .married() = false;. С тех пор косо посматриваю на безпрефиксные геттеры и сеттеры. Ну а проблем расширить C# при этом никогда не было: named parameters в C# 4, properties изначально, и т.д. и т.п. (Сам пишу 90% времени на С++).
Да, надо геттеры делать константными, что также будет ожидаемо для пользователей API. Иначе возможны гораздо более странные примеры.
От безысходности.

А почему не просто от разумности? Какой-то идиот когда-то придумал писать get_xxx() вместо просто xxx() и все за ним повторяют. А эти просто не стали.


properties изначально

Только лучше ими по возможности не пользоваться. Так как properties имеют сильно расширенную семантику по сравнению с филдами и методами: property descriptors и всё что через них работает. Если я встречаю где-нибудь в десктопной программе property вместо метода, я вынужден искать, нет ли где на неё binding'а или сериализации или ещё чего-то такого.

Соглашусь! Реализация адекватных property-классов обёрток в C++ — то ещё развлечение. Обычно «узбагоиваемся» и делаем наподобие такого:

#include <iostream>

class C {
private:
  struct { int field; } fields;
public:
  int field() const { return fields.field; }
  void field(int v) { fields.field = v; }
};

int main() {
  C c;
  c.field(12);
  std::cout << c.field();
}
добавьте named orderless function arguments

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


void some_function(int, int, int);
А ещё отдельный котёл в аду должен быть предусмотрен для того, кто решил, что возможность опускания имён параметров в объявлении функций — это нормально.

А если это tag dispatch?
Там не принято именовать фейковые аргументы. Варнинги одна из причин.

Если это внутренний код библиотеки, не предназначенный для чтения её пользователем, то никаких проблем. Но когда такое пролазит в публичный интерфейс, то теряется самодокументированность кода.

Фича языка от этого никуда не денется.
Да, в C++ есть многое, что не нравится многим другим.
И ктото, возможно, считает также что авторы UB или aliasing`а или Elvis operator`а должны быть к том же котле.
Особенно есть множество фич которые можно использовать во вред или неправильно. Но это не повод обижать авторов какой то фичи, а повод задуматься о причине по которой она появилась в языке.
Так же все эти фичи делают C++ таким какой он есть, не похожем на все остальные.
Есть два вида языков. Одни все ругают, на других никто не пишет. (с) Бьярне Страуструп.

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

Похоже, стоит развернуть свою мысль подробнее.


Так вот, если у вас есть функция foo(int, int, int); то имена не помогут, потому что, среди прочего:


  1. Имена не видно в точке вызова функций: пусть у вас есть foo(42, 3600, 29) или foo(bar(), baz(), meh()), толку с имён-то?
  2. Имена не защищают от опечаток. foo(secs, life, ack(3, 2)) никак не отличается от foo(life, secs, ack(3, 2)) с точки зрения компилятора.
    2а. Если вы вдруг поменяете API и порядок/семантику аргументов, то компилятор тоже не даст вам по рукам.
  3. Имена не дают полной информации. int time — это что? Время в секундах? В миллисекундах? Уже 8 лет как есть std::chrono, например.
Имена не видно в точке вызова функций

Это от IDE зависит. В случае с С# и VS имена аргументов как раз видно в точке вызова.


Имена не дают полной информации. int time — это что?

Они дают больше информации. Другое дело что имена надо тоже правильно давать.


Если вы вдруг поменяете API и порядок/семантику аргументов, то компилятор тоже не даст вам по рукам.

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

Это от IDE зависит. В случае с С# и VS имена аргументов как раз видно в точке вызова.

А пуллреквесты на гитхабе (возможно, своём тырпрайзном) или фабрикаторе вы тоже в VS ревьювите?


Или там, не знаю, git blame какой-нибудь.


Они дают больше информации.

Естественно, с именами лучше, чем совсем без. Но поинт в том, что если вам в коде без имён параметров не разобраться, то изначально с ним что-то не так (и я, собственно, перечислил, почему).


Что лучше, start_periodic_digging(int period, int start_time, int length) или start_periodic_digging(std::chrono::duration, std::chrono::timepoint, my_cool_length)? И вы же не будете утверждать, что start_periodic_digging(int period_in_msecs, int start_time_since_1970, int length_in_km) лучше предыдущего варианта без имён переменных?


Другое дело что имена надо тоже правильно давать.

Только имена вы даёте на порядок-другой чаще, чем создаёте новые типы, поэтому и глаз замыливается, и лениться более охота.


Поэтому когда аргументов много и/или есть относительно высокий шанс спутать их порядок, то рекомендуется использовать DTO.

Да, это тоже отличный вариант. Особенно в этом нашем C++, как только стало известно, что давно де-факто поддерживаемые designated initializers завезут официально в C++20.


Но DTO — это тип, а значит, моё исходное утверждение в силе :)

А пуллреквесты на гитхабе (возможно, своём тырпрайзном) или фабрикаторе вы тоже в VS ревьювите? Или там, не знаю, git blame какой-нибудь.

Хороший вопрос. Никогда не обращал внимания есть там это или нет:)
Но даже если и нет во время ревью, то как минимум в разработке это есть и помогает.


И вы же не будете утверждать, что start_periodic_digging(int period_in_msecs, int start_time_since_1970, int length_in_km) лучше предыдущего варианта без имён переменных?

Это конечно достаточно субъективно и вопрос привычки. Но могу сказать с тех пор как мы среди всего прочего стали следить за более-менее "говорящими" именами методов, переменных и параметров, то лично мне работать стало гораздо удобнее.


Только имена вы даёте на порядок-другой чаще, чем создаёте новые типы, поэтому и глаз замыливается, и лениться более охота.

Тоже кстати вопрос привычки. Поначалу было сложно и часто приходилось размышлять над подходящим именем. Сейчас уже всё как-то на автомате происходит.


Но DTO — это тип, а значит, моё исходное утверждение в силе :)

Ок, тут не поспоришь, пункт за вами :)

Подставим вместо foo какой-нибудь operator -. Упс, кажется, все эти возражения уже не так хорошо смотрятся :-)

Хм, а почему?


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

Сигнатура (int, int, int) вообще "не очень" по сути своей, там уже явно тянет отдельной структурой Params.

Зависит от конкретной ситуации и требований. С методом, допустим, принимающим восемь строк очень неудобно и ошибкоопасно работать — а это случай из реальной практики. Обертка всего этого в DTO убрала кучу «случайных» ошибок.

А мы и не говорим о функциях, принимающих восемь параметров. Разумный максимум — 3-4 параметра. Имеет ли смысл заворачивать их в DTO — большой вопрос хотя бы из соображений удобства вызова функций и эффективности (соглашения о вызовах, передача аргументов через регистры на x64 архитектуре).

3-4 однотипных — «ну неудобно». С т.з. производительности, конечно, нужно смотреть в каждом конкретном случае. В том же C++ влияние на производительность от «дополнительных DTO» — гораздо сильнее, чем в managed-языках, но ключевой момент именно в балансе «удобство\эффективность\производительность», в зависимости от конкретных целей и задач.
Вы сами ответили на свой вопрос: чтобы получить удобоваримые properties, они должны быть в языке, как они сделаны в C#. Макросы — это временная заглушка для разных проблем, которые нужно решать правильно, а не «как получилось».
Та properties есть везде кроме стандарта. А в стандарте их нет только потому что любой стандартизированный/нативный для ядра языка формат будет ущербный по сравнению с тем что можно запилить на шаблонах за несколько часов.
А зачем вообще нужны проперти в классах? Вроде существует рекомендация делать публичные поля в структурах под это дело
Дмитрий: Ну, zero cost abstraction — это ассемблер. Если мы хотим вообще zero cost abstraction, надо писать всё на ассемблере.

Ребят, после этой цитаты хоть кто-то серьёзно относится к этой дискуссии?
«Всем известно, что нет ничего глупее споров «какой язык лучше»»
@
«Давайте устроим спор какой язык лучше»
Мне кажется, что сама попытка сравнить некорректная.

Шарпы — это язык общего назначения. С развитием Blazor и Core он позволяет писать на одном стеке хоть под браузер, хоть для сервера на Линукс. Это удобно тем, что позволяет использовать одинаковые библиотеки, шарить модели и логику и эффективнее использовать разработчиков между различными частями проектов. И хотя дотнет сделал гигантский шаг вперед в производительности с Core и аппаратными инструкциями, это все еще очень быстрая платформа общего назначения.

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

Соответственно, никто не будет писать промышленный веб-портал helpdesk на плюсах, ибо затраты на разработку никогда не окупятся выигрышем в железе. И наоборот, никто (почти) не будет пытаться писать драйвера на C# cosmOS Поэтому что тут сравнивать, я не знаю.

П.С. Что касается обучения, то очевидно, текущий подход устарел. Нет никакого смысла учить людей пузырьковой сортировке потому что обычное программирование давно ушло от решения низкоуровневых задач к высокоуровневым. Я думаю 99% Дотнет разрабов понятия не имеют, как под капотом в Linq сортируются массивы, что не мешает им писать хороший и быстрый код. Алгоритмы сортировки и их реализация, тонкости размещения объектов в стэке нужны только компьютерным специальностям (а программирование у нас учат все технические, а не только программисты) и то, после того, как они научатся использовать стандартные фреймворки.

Я бы сейчас бы учил бы людей как раз на C#:
1) Основам синтаксиса
2) Правилам оформления кода
3) Программированию вида Asp.Net Core Blazor в самом простейшем виде
4) Умению находить и использовать готовые пакеты (а-ля выгрузку в эксель и логирование)

Такой курс позволил бы иметь готовые проекты, немного разобраться в экосистеме и не утонуть в магии указателей. Так как я преподавал даже не C++, а Дельфи, и люди уже не понимали что и как. И вот когда с простейшими вещами проблем не будет, вот тут уже можно рассказывать, а как оно на самом деле происходит.
Вы ничего не перепутали? Язык с GC универсальным быть не может по определению. Соответсвенно шарп — это узконишевый язык, основное назначение которого — кастомизация кодом сборок компонентов WinForms/WPF. При этом шарп имеет принципиальные противопоказания к применению в подавляющем большинстве задач индустрии, особенно в наиболее актуальных на сегодняшний день — робототехнике и промавтоматике.
А вот плюсы — это таки универсальный язык по определению, и годен к применению в любой сфере.

Подавляющее большинство программирования — это backend, frontend, всякий банковский софт и прочий кровавый энтерпрайз. А вот робототехника и промавтоматика — это нишевые области.

Да что вы. Реальный экономический выхлоп дают таки только робототехника промавтоматика и счет по наукам. Вспомогательным является учет, в т.ч. банковский. И даже при том что в этих сферах работает 10% от общего количества разрабов, это и есть 100% разрабов с профессиональным образованием, которые и решают 99% задач индустрии вообще. Все же остальные казуалочки и социалочки — это сфера личного потребления и соответсвенно не более 1% задач и потока финансов индустрии, а соответственно и натягивают туда неквалифицированных разрабов, пытаясь скомпенсировать качество количеством. Вот как раз для таких шарп и предназначен. И именно поэтому основан на яве, которой моск в американских школах насилуют всем поголовно, И Майкрософт прекрасно понимали в исходе абсурдность пытаться создать на этой ошибке природы каких либо профессиональных средств разработки. Но нужна был им как раз замена ворд, эксель и визуал бейсика, позиционируемого как средства для мелкой кастомизации готового софта и создания мелких утилит, производимых непрофессионалами.
Сфера личного потребления — это 1% потока финансов индустрии

Поскольку в развитых странах на сферу услуг приходится 70-80% всей экономики, было бы очень любопытно увидеть какие-нибудь источники, подтверждающие ваши слова о «1% потока финансов».
Ну в промавтоматике языки общего назначения используются редко. В основе там iso 61131.
А вот робототехника это эмбеддед со всем вытекающими на С/С++.
Ваша реакция на C# неадекватна, при том, что совершенно точно вы не писали на нем годов с 2005х, т.к. ваши представления о производительности, сборщике мусора и прочем явно с тех пор.
Кроме того, ваше восприятие рынка также неадекватно. 95% софта — это как раз средства автоматизации управления предприятиями, банковский софт и прочие сайтики-визитки. Именно для этого и нужен C#. Я вот взял, и построил простенький сайт с нуля на Asp.Net Blazor за день. При этом у меня и с базой работа, и логирование, и бизнес-логика и UI. По факту — готовый проект. Жрет, если правильно работать с ORM порядка 100-120мб памяти с одновременной работой 30 пользователей. А если добавить кэширование, то web-api может десятки тысяч запросов в секунду держать.

А теперь, внимание вопрос. Сколько времени у вас займет написать такое на C++? Что бы и с базой работало, и чтобы логи были, чтобы шаблонизатор был для UI и чтобы перформанс был выше, чем на C#? Ну и чтобы это все можно было поддерживать и было читабельно. За неделю управитесь? Или вам месяц нужен?

Еще раз, платформа и язык общего назначения — это такая платформа, которая позволяет решать 90% задач дешево и эффективно. Я на ассемблере могу написать вообще все, но он никаким боком не будет общего назначения, так как сложно, дорого и долго.
Все так. Делфай, к слову, тоже получил нормальные Web библиотеки (UniGUI, TMS Web Core) — все быстро, удобно и просто — накидал формочки, воткнул коннекты к базе, и через день у тебя готовое веб приложение на 5-10 форм. Не нужно вникать в JS. Не нужно делать связку бэк <> фронт, все максимально само. Можно и какой-то ORM добавить — mORMot, например. Тогда и SQL нужен постольку.
Что бы и с базой работало,
Для этого код писать не надо от слова совсем.
и чтобы логи были,

Вы считаете трудной задачей заменить cout на другое название а «Hello World» на другую строку? Все с вами ясно.
чтобы шаблонизатор был для UI
Подробнее можете рассказать что вы под этим понимаете?
чтобы перформанс был выше, чем на C#

Знаете есть такое сравнение — тормозит как скайп. Или хотите сказать скайп не шарпом изуродовали?
За неделю управитесь? Или вам месяц нужен?

Вы главное не забывайте что C# builder aka WinForms это настолько жалкий обрубок Дельфы и С++ Builder что борланд который его делал просто отказался участвовать в релизе. Причем обрубок именно в продуктивности именно создания средств учета. Ну и еще один такой момент не путайте языки и фреймверки это две большие разницы. Да и вам же в первую очередь контраргумент. Потому что именно в плане фреймверка именно визуальной разработки именно средств учета/БД шарп и сливает по определению. При этом у шарпа он один. А у плюсов их много.
Знаете есть такое сравнение — тормозит как скайп. Или хотите сказать скайп не шарпом изуродовали?

Ядро Скайпа на С++, гуи старой версии на Delphi а новой версии на electron, так что да C# тут непричём
Для этого код писать не надо от слова совсем.


А как у вас C++ код будет читать записи с сервера БД? Ну я даже нашел ORM ODB, но синтаксис и объем мусорного кода там гигантский, а таких фишек как группировка и возврат анонимных типов такого небось еще 10 лет не будет.

Вы считаете трудной задачей заменить cout на другое название а «Hello World» на другую строку? Все с вами ясно.


Вы не поверите, но в нормальном мире логи желательно отправлять на отдельный сервер, обычно это MongoDB, ну и там опять-таки нужно уметь с этим работать. В богомерзком C# есть возможность простым измением конфига писать сразу в 20+ платформ serilog. А как у вас там в C++?

Подробнее можете рассказать что вы под этим понимаете?

Шаблонизатор это модуль, который на входе берет ваш шаблон с разметкой и кодом, а на выходе выдает метод, на вход которого подаются данные, например из таблички БД, а он генерит HTML код. Кстати, в богомерзком C# сейчас рассматривают возможность заменять HTML например на WPF, и внезапно, можно будет одну и ту же UI логику использовать и для веба, и для десктопа.

Знаете есть такое сравнение — тормозит как скайп. Или хотите сказать скайп не шарпом изуродовали?

Как вам уже сказали, скайп ни разу не был написан на C#. Снова два балла, пересдача.

Потому что именно в плане фреймверка именно визуальной разработки именно средств учета/БД шарп и сливает по определению. При этом у шарпа он один. А у плюсов их много.

У Шарпа есть вот просто для БД: EF, EF Core, NHibernate, Dapper, чистый ADO.Net в зависимости от того, что хочется/нужно. Что там есть у плюсов из ORM, чтобы хоть наполовину бы закрывало то, что умеет EF, я не знаю.

Короче поток бреда такой, что я даже не знаю, как это комментировать. Ясно видно, что гражданин крайне далек от разработки и его познания окончились видимо на C++ Builder в 2005 году, до релиза .Net 2.0
>>Короче поток бреда такой, что я даже не знаю, как это комментировать.

зато это бред уже третий день развлекает, спасибо и крепитесь :)
Кроме того, ваше восприятие рынка также неадекватно. 95% софта — это как раз средства автоматизации управления предприятиями, банковский софт и прочие сайтики-визитки

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

А что за Царь? А то вижу уже второй или третий раз отсылку в очень характерных контекстах.

Да был (и в каком-то виде есть) такой персонаж на linux.org.ru. С характерным стилем и тезисами. А также клоны и подражатели. Один из основных тезисов (как он мне запомнился) такой: "всё можно и нужно писать на Си, а что нельзя писать на Си, то и не нужно".


Но он (как виртуальная мультиличность) не только и столько на абстрактные темы вещал, а в обсуждении конкретики участвовал, вещая дурь вперемешку с разумными и верными утверждениями, и с невероятным апломбом по типу "вы все ламерьё, вебнули, обезъяны, а я — Царь сишечки".


Вот пример: https://www.linux.org.ru/forum/development/15256164?cid=15260615

Да что вы. Реальный экономический выхлоп дают таки только робототехника промавтоматика и счет по наукам. Вспомогательным является учет, в т.ч. банковский. И даже при том что в этих сферах работает 10% от общего количества разрабов, это и есть 100% разрабов с профессиональным образованием, которые и решают 99% задач индустрии вообще. Все же остальные казуалочки и социалочки — это сфера личного потребления и соответсвенно не более 1% задач и потока финансов индустрии

Ну вот смотрите: я работаю на транспортный концерн. За то время что я на него работаю мы ввели в строй систему оптимизации маршрутов и загрузки грузовиков. По прикидкам концерна это минимум 4-5% сэкономленных километров. А местами и все 10%. Звучит может быть немного, но если взять тысячи грузовиков и миллионы(а то и миллиарды) километров, то получается совсем неплохой "экономический выхлоп".


Ещё мы перевели почти всю сопроводительную документацию с бумаги в дигиталку. А это тонны сэкономленной бумаги и огромное количество сэкономленных человекочасов. Тоже никто не жалуется.


И всё это на "казуальном сишарпе". Так что прежде чем подобные заявления делать было бы неплохо сначала хотя бы чуть-чуть проинформироваться.

И всё это на «казуальном сишарпе»
Только вот весь остальной мир делает это на нативных языках. Потому что они позволяют иметь гораздо более продуктивные в этом плане фреймверки с гораздо более развитыми средствами визуальной разработки.

Если у вас есть статистика, то я с удовольствием на неё посмотрю. А так вы уж извините, но это для меня больше похоже на какие-то ваши личные фантазии.


П.С. И особо интересно мне было бы посмотреть на процент написанных иключительно на нативном языке "экосистем", включающих в себя в том числе и десктоп-приложения, B2B сервисы, веб и мобильные приложения.

Все очень просто. Ты разрабатываешь Великую Бухгалтерскую Программу.

При этом сидишь за компьютером, БИОС которого написан на Си, ОС на Си, все драйвера на С, IDE тоже возможно на Си. Итого статистика 1:10 =)

И стул, который пригорает, тоже спроектирован в написанном на С CAD'e )))

Это уже другое и я нигде вроде бы не утверждал что нативные языки вообще не нужны или не используется.

И особо интересно мне было бы посмотреть на процент написанных иключительно на нативном языке «экосистем», включающих в себя в том числе и десктоп-приложения

Ну есть статистика по поддерживаемым лицензиям на средства разработки. Для Дельфы/билдера это 500k действующих лицензий. Т.е. практически весь сектор внутрикорпоративного софта крупных корпораций и его веб-мосты. Таких как Сименс, Самсунг и т.д.
И по продуктивности есть кое какая инфа. К примеру среднестатический клиент-банк для корпоративного клиента (это с сервером и рабочей группой на стороне клиента мультиподписями синхронизацией баз, процессингом, его изоляцией как внутренней так и внешней, завязкой на аккаунт-менеджеров, подсистемой администрирования ключей и т.д. мелочью) делается на дельфе или билдере двумя разрабами среднего пошиба месяца за два-три.
И по шарпу с жабой есть интересные наблюдения. Значит есть тут три индустриальных гиганта в городе. Два металлургических и один машиностроительный. Так вот пришли мы на практику в 98-ом на один из них у них там как раз новый отдел — новую ERP R3 внедряют. Там типа сверхпродуктивный язык кастомизации новейший ява. Ну договорились что друг другу не мешаем и разошлись (мне как бы на свой машиностроительный гигант бежать надо было к самому группа практикантов с технаря должна прийти была). Ну в общем к 2002-ому где то так внедрение полным ходом шло на всех трех гигантах. Потом там язык поменяли на новейший шарп и винформз все эти три отдела возрадовались наконец то мы ее докастамизируем (одним из этих отделов к тому времени уже мой одногрупник руководил так шо видел как они там типа рады были по самые немогу). Ну в общем суть в том что на металлургических гигантах ее до сих пор полным ходом внедряют. А машиностроительный 5 лет назад обанкротился и закрылся.
Ну есть статистика по поддерживаемым лицензиям на средства разработки

Посмотреть на неё можно где-то?


Для Дельфы/билдера это 500k действующих лицензий.

И что это должно доказывать? Особенно в контексте моего вопроса?


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

А это то вообще причём? И если уж, то за какое время такое же делается "двумя разрабами среднего пошиба" на других языках? Ну для сравнения.

И если уж, то за какое время такое же делается «двумя разрабами среднего пошиба» на других языках?
Это в первую очередь вопрос не языка. Это вопрос умения фреймверка работать с созданием системы учета по принципу zero code. Т.е. преимущественно визуальная разработка в первую очередь бизнес-логики работы с БД. Т.е. используется факт что оформление информационной постановки на компе по телодвижениям почти на 100% совпадает с реализацией. И вот ни ява ни шарп подобный принцип визуальной разработки бизнес-логики потянуть не смогли. Как Борланд не старались их этому обучить, даже в случае шарпа совместно с майкрософтом. GC мешает. Он лишний в ООП.
Это в первую очередь вопрос не языка.

Да неважно вопрос чего это в первую очередь. Приведите сравнение с альтернативными вариантами. Тогда это можно обсуждать.


П.С. Пока я если честно вижу кучу какой-то отсебятины и перепрыгивания с одного на другое. И слабо понимаю о чём это, зачем это и какое отношение это имеет к обсуждаемой теме.

Ну вот соседний с ними банк уже лет 10 все допиливает и допиливает свой клиент-банк на яве целыми двумя офисами в двух городах. Ну он правда на частного клиента ориентирован с одной стороны проще с другой вроде как объемней с третьей интеграцию с внутренними системами клиента и мультиподписи обеспечивать не надо, c четвертой интерфейс клиентский у них по определению веб а из html формат описания гуя никакой. Ну кое что более менее внятное оформилось. но как бы элементарных поисков нет хотя писал им на этот счет еще лет 5 назад (сам пользуюсь неудобно) сказали дада надо сделать. Ну как бы эту кухню я изнутри не видел. Но насколько понимаю срамо-агилом во всю воняет.
Ну вот соседний с ними банк уже лет 10 все допиливает и допиливает свой клиент-банк на яве целыми двумя офисами в двух городах.

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

Хорошо. Давайте по другому. Потому что так можно все что угодно моя твоя не понимает. Надо или одной компании продукты сравнивать на обоих языках, причем одного направления. Но это бессмысленно. Потому что весовая категория разная. Единственное где так получается сравнить — это сама винформз с VCL. VCL практически монополист в своей нише. WinForms разработчик в релизе участвовать отказался. Релиз Delphi.NET тоже закончился эпическим фейлом. Настолько куцей и непродуктивной была по сравнению с нативной. Точно так же как и майкрософтовская С++.NET живет только потому что MS конкуренцию в нативном проиграл с треском а менеджед купил — т.е. понял что не его уровня задача и даже для себя не может сделать, а другого средства доступа к WinForms нет.
Или конкректно с графами и диаграмами показывать почему GC без ручного решения задачи управления взаимосвязями не способен обеспечить работу взаимосвязей по правилам ООП. Что и не позволяет вести на нем полноценную ООП разработку. А соответственно ни высокопродуктивных средствпреимущественно визуальной разработки бизнеслогики использовать не может, ни продуктивности разработки кода сравнимой с нативными языками, а особенно имеющими современные средства автоматики, не будет. Ей богу как будто на третьем курсе теорию графов не проходили и правила взаимосвязей в ООП — композиции и агрегации тоже никогда не слышали.
Единственное где так получается сравнить — это сама винформз с VCL.

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

И о чём нам именно это сравнение должно говорить?

WinForms — примитивная формошлепка. Вся бизнеслогика кодом включая доступ к БД.
VCL — формошлепная часть 10% остальные 90% — разработка бизнес-логики по принципу no code
Или конкректно с графами и диаграмами показывать почему GC без ручного решения задачи управления взаимосвязями не способен обеспечить работу взаимосвязей по правилам ООП.

Давайте, было бы интересно увидеть.
современные средства автоматики


Пелевин. Омон Ра.


Он произносил слово "автоматика" с такой чистой и мечтательной интонацией, что его лубянский кабинет, куда мы поднимались слушать лекции, на секунду словно превращался в резонатор гигантского рояля, но, хоть это слово всплывало в его речи довольно часто, никаких технических сведений он нам не сообщал, а рассказывал в основном житейские истории, или вспоминал, как партизанил во время войны в Белоруссии.
Ну считайте дважды два. В мире порядка 20 миллионов разрабов всего. из них с в/о по специальности порядка 2 миллионов. Ни в сектор корпоративного а тем более банковского учета, ни тем более в сектор автоматики без в/о не пустят. примерно 3/4 работают в сфере АСУТП, САПР и счета по наукам. и примерно оставшиеся пол миллиона в корпоративном учете. С учетом того что ни САПР на билдере не делают (ну там на вижак сели плотно еще в начале 90-х, вернее тогда он назывался MSC++), и в АСУТП если и пригоден фреймверк то очень ограниченно на выделенных терминалах. Ну в счете по наукам каую то часть лицензий юзают точно. Билдер в основном сюда позиционируется, в системы учета в основном дельфа. А остальные то где могут быть? А особенно если абсолютно точно известно что Борланд и потом Эмбаркадеро именно на крупные канторы ориентировано, а на мелочь им даже судя по их техническим решениям глубоко пофиг? Ну и продлевают эти лицензии как понимаете не для того чтобы они на полочках пылились.
Для Дельфы/билдера это 500k действующих лицензий
Более трех миллионов, если что.
Более трех миллионов, если что.

ну более трех миллионов то и прибрехать местами диллеры могли. или посчитать всех клиентов за все существование в том числе вышедших студенческих в те времена когда комьюнити-лицензии не было. А вот цифра более 500k. кототрую на эмбаркадере как то видел — ну это из серии точно не меньше. Хотя с Германии знакомые рассказывали — дельфа/билдер/плюсы/ада — другое не котируется в том числе в универах так и говорят — натив а то работу не найдете. У них там правда ситуация совсем не как у нас.
Хотя с Германии знакомые рассказывали — дельфа/билдер/плюсы/ада — другое не котируется в том числе в универах так и говорят — натив а то работу не найдете. У них там правда ситуация совсем не как у нас.

Вы знаете это очень интересно выглядит когда кто-то, со слов каких-то мифических знакомых, рассказывает людям живущим и работающим в Германии, что они оказывается работу не найдут...


И я вам ещё раз скажу: чушь вы полную несёте. В Германии сейчас нужны программисты практически на всех языках. И вот вам кстати для примера информация на тему самых востребованных программистов и языков:
https://entwickler.de/online/development/top-10-programmiersprachen-redmonk-tiobe-pypl-579886370.html
https://jaxenter.de/it-trends-deutschland-sprache-gehalt-tools-85752
https://t3n.de/news/programmierer-gesucht-developer-studie-programmiersprache-881255/


Надеюсь поймёте что там написано. В крайнем случае гугл-транслэйтор вам в помощь или друзей попросите перевести.

Ну есть статистика по поддерживаемым лицензиям на средства разработки. Для Дельфы/билдера это 500k действующих лицензий. Т.е. практически весь сектор внутрикорпоративного софта крупных корпораций и его веб-мосты.

Как эта статистика учитывает лицензии на компиляторы gcc или clang и такие популярные средства разработки на C++, как голый vim?

А при чем тут билдер к gcc? У нас же разговор пошел про высоко продуктивные фреймверки? Ну под плюсы их разных хватает. В том числе под стандартные плюсы. И все куда попродуктивней WinForms/WPF будут которыми шарп ограничен.
А это только про эмаркадеру. Ее фреймверк ее расширений требует. другие компиляторы с ним работать не будут. Хотя у самого него компилятор на основе __clang сделан.
Но тут сравнение с шарпом и винформзом очень показательное. Одного папши детки то.
Очень странный спор, когда коснулись GPGPU даже не упомянули про OpenCL хотя он как раз кроссплатформенный, что может даже работать на CPU. Но вообще я все же за C# так как он покрывает очень много бизнес кейсов и гораздо удобен для них нежели С++. C# проще учить и на нем проще делать отладку. А во многих нишах, где требуется более низкоуровневое программирование, высокая производительность я бы использовал чистый Си или Rust. Таким образом я не вижу для каких задач С++ подходил бы лучше чем C#/Java, Си/Rust, TypeScript, python.
Таким образом я не вижу для каких задач С++ подходил бы лучше чем C#/Java, Си/Rust, TypeScript, python.

А если мыслить категориями не задач, а рыночными нишами?

Сколько на этой неделе можно нанять разработчиков на Rust?
Какой процент разработчиков на python готовы писать и отвечать за написанное в многопоточной среде?
Сколько можно найти C# девелоперов с многолетним опытом в эмбеддед и линукс?

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

"Что и требовалось доказать" — язык нужно выбирать под задачу. Подавляющее большинство задач "общего назначения" — лучше решаются на C#, чем на C++, т.к. C++ сейчас является всё-таки языком "местного назначения".
Он рвёт в клочья в определенном наборе задач, но слишком сильно удорожает разработку "in general".
P.S. Сам знаю оба, использую по уместности.

Он рвёт в клочья в определенном наборе задач, но слишком сильно удорожает разработку «in general».

Да дороже. Сейчас чаще получается рейты у плюсовиков выше, а доступность дешёвых ниже. Но ведь это не проблема языка, а резко возросший спрос рынка. Вот, например, в Киеве зашло около 10 крупных проектов, и спылесосили они всё что было доступно аж до уровня 4000usd по зарплате.
Понятное дело, что многие сферы, включая эмбеддед, перешли на более доступные альтернативы, и писать формочки/мобильные приложения/казуалки готовы на чем угодно только не С++. Шесть лет назад ситуация была сильно противоположная, думаю развитие языка дало сильный стимул рынку.
Он рвёт в клочья в определенном наборе задач, но слишком сильно удорожает разработку «in general»

При этом очень сильно снижает TOC.
Подавляющее большинство задач «общего назначения» лучше решаются на C#, чем на C++,
— Ну к примеру ни одного САПР общего назначения на шарпе еще никто не видел. И ни одной СУБД общего назначения. И ни одного вебсервера общего назначения. И ни одной оси общего назначения. И не увидят никогда. Потому что если шарп таки довести до ума и сделать таки универсальным языком то получатся таки плюсы а не что то другое.
Вы так здорово скинули Си со счетов. Embeded лучше писать на Си, а прототипировать на python. Что то многопоточное очень удобно пишется на Go. Разработчики на Rust на рынке присутствуют в принципе. С++ хорошо подходит там, где много готового кода на С++ нет смысла переходить на что то еще. То есть С++ может в принципе неплохо справится со всем, но слишком немного задач, где бы он подходил лучше всего.
Не понятно почему Embedded лучше на C. C++ в чем — то уступает? Если это размер бинарника, то с отключенным rtti + exceptions отличия не должны быть существенно заметны для идентичного кода. В тоже время гораздо больше возможностей, огромная библиотека и выразительные конструкции которых нет в C. Яркий пример constexpr массивы которых порой очень не хватает и многие пишут кодогенераторы (частотные фильтры, флэш таблицы тригонометрии и прочее подобное).
Если это не совсем экстремальный эмбеддед с сотнями байт памяти, а что то уже за 5$ (cpu+ram), то там уже можно ставить boot to Qt и иметь вполне достойный инструментарий.

Не понятно почему многопоточное нельзя удобно писать на C++. Применяя правильные паттерны и абстракции я ни разу за 5 лет (Серверное ПО 100+ процессорных ядер) не столкнулся о проблемах о которых спрашивают на собеседованиях( deadlocks, race conditions, false sharing, memory barriers и пр). Более функционального и более удобного апи для векторизации и распараллеливания и многопоточности чем в с++ вообще мало где есть.

Опять же непонятно, почему прототипировать лучше на каком то языке, отличном от того, на котором будет разработка продукта. Поддерживать 2 и более кодовых базы в согласованном состоянии это невероятно сложно даже в рамках одного языка программирования. Даже если это 2к строк канонического+сайнтифик R\perl\python с 60% изменений, но которые дифф не может вообще никак сопоставить — это ад, и порой проще запортировать заново.

Если это размер бинарника, то с отключенным rtti + exceptions отличия не должны быть существенно заметны для идентичного кода.

Притом во многих случаях на C++ даже код на C компилируется в меньшее по размеру и работает быстрее ;)

Вот пример:


https://inobitec.com/products/dicomviewer/


Особенности: высокие требования к производительности, расчет как на CPU, так и на GPU с помощью OpenCL или CUDA, по-максимуму общая кодовая база как для разных десктопных платформ (Windows, Linux, MacOS X), так и мобильных (iOS, Android) — понятное дело, для мобильных в несколько облегчённом виде, но тем не менее. Сейчас это написано на C++ с использованием Qt. Как бы вы это писали на C# и с помощью чего?

Посыпаю голову пеплом, свою же область, на что учился, я и позабыл. Да, компьютерная графика всецело за С++. Хотя пока учился, то делал все из той же области на C# используя библиотечку OpenTK (OpenCL + OpenGL + OpenAL) кроссплатформенности тогда конечно же не было, сейчас вроде можно сделать и кроссплатворменно. Но С++ тут все же должен быть удобнее.
Я его не упомянаю потому что OpenCL существенно хуже CUDA по всем параметрам кроме проприетарности. Кода в 2 раза больше, инструменты отладки «как повезет» (CUDA Toolkit шикарный) и идея о том что один и тот же код можно писать и запускать и там и там — это идиллия, т.к. по факту все алгоритмы приходится все равно переписывать в стиле SIMT, а если нужно что-то дернуть из C++, никто не мешает пометить функцию как __device__ __host__.
Delphi/Lazarus в помощь: кроссплатформенность, быстрая сборка, второй работает на чем угодно вплоть до утюгов :) Интерефейсных компонент хватает, не нужно одним Qt ограничиваться (к слову — под него Lazarus) тоже собирает бинари. На распебери Лазарь не только собирает бинари но и среда работает.
Lazarus и Delphi это IDE. А язык называется Pascal. По возможностям он не отличается от C/C++, а по безопасности и удобству близок к C#. Производительность кода ограничена только качеством компилятора. Впрочем, можно прямо в коде использовать ассемблер, не полагаясь на компилятор.

Delphi — это и язык, и IDE.
Разница между Delphi и Pascal такая же, как между C++ и C.

DistortNeo прав, язык и самом деле называется Delphi. До определённой версии он назывался Object Pascal, но в Delphi 7 его переименовали в Delphi, так что с тех пор это действительно и IDE, и язык.

Формально — да. Хотя, разница между ObjectPascal и Delphi только в автоматическом разыменовывании типизированных указателей. То есть, можно не ставить @ и ^ во многих случаях.

В Lazarus и FreePascal это просто опция компилятора.
Нет такого понятия как ObjectPascal. Есть Паскаль ISO/IEC 10206:1991 и есть недоразумение в виде Дельфи, которое меняется с каждой версией.

По безопасности и удобству он далеко взаду. А качество компилятора FPC описывается фразой «нативный неоптимизирующий компилятор»

Но в целом, надо было просто распознать сарказм в
Из справки Delphi 7:
Delphi is a high-level, compiled, strongly typed language that supports structured and object-oriented design. Based on Object Pascal, its benefits include easy-to-read code, quick compilation, and the use of multiple unit files for modular programming.

Насчет ISO Pascal все понятно, это документированный стандарт, эталон. Как ANSI C.

Всякие Delphi, ObjectPascal, TurboPascal, VirtualPascal, FreePascal, PascalABC и прочие — диалекты, в которых что-то добавлено. Но в целом, ObjectPascal это ISO Pascal + OOP. Как C++, у которого тоже разные диалекты.
У Builder C++ расширение файлов .cpp, у Microsoft C++ расширение файлов тоже .cpp
Удачи с компиляцией Builder в MS Visual Studio

А при чём тут компиляция? Не смотря на приводящую к несовместимости разницу в деталях, это всё еще один язык, С++.

какой смысл несет эта фраза: «это всё еще один язык, С++», если приложение по факту придется портировать из одного C++, в другой С++, для компиляции, а это практически означает, что не все C++ одинаково равны.

C# писали в том числи люди из Borland-а.
Отсюда всеми любимые property в C#.
Правда некоторые любят заявлять что Borland мертв и там нет ничего полезного, забывая что много фишек C# это по сути Delphi/Builder
Всё так. Шарп многие хорошие вещи позаимствовал. Шарп мне нравится как язык. Не нравится дотнет как платформа. К сожалению, Шарп так и не научили нативной сборке. К слову — даже Лазарус научили для JIT собирать :) А вот наоборот — увы.
К сожалению, Шарп так и не научили нативной сборке

AOT давно есть, как минимум в Mono и используется активно в приложениях под iOS.


В Core 3.0 есть R2R images — AOT-сборки приложений.

Ну, зато виртуальная машина может, например, затюнить код для той или иной архитектуры.

очень странный аргумент. Мы можем скомпилировать плюсы в байткод вм и выполнять на целевой платформе. О состоятельности такого подхода можно судить в первую очередь по его популярности.
Когда-то разрабатывал только на С++ и был большим фанатом языка, писал для Embedded и библиотеки. Радовался уникальным пятиэтажным сочетаниям разноплановых языковых конструкций, а порой и макросов, которые позволяли мне получить гибкое решение для очевидных логических задач в стиле «вызови мне то, пока еще не знаю что». Каждый год чувствовал, что ну вот теперь-то я прокачался в языке — то OOP то templates, то Design Patterns, то S.O.L.I.D., то еще чего… Другие языки периодически посматривал, но как-то они не цепляли — ни Java, ни C# ни Python. А потом решил перейти на удаленную разработку, оказалось, что на С++ это сложно, начал учить web, и естественно javascript. А в javascript вдруг оказалось, что 90% всех моих логических задач решает то, что функция — это одновременно класс, объект, замыкание и экземпляр. То есть всего одна гибкая языковая конструкция решает все задачи. Добавьте к этому async/await для «многопоточности», для понимания которой кроме этих двух слов ничего не нужно. Добавьте typescript только, чтобы объявлять интерфейсы, которые так и так где-то все равно пришлось бы объявлять для документации, и которые при этом позволяют отлавливать ошибки рано, чем так гордится С++. И по сути, это все, что нужно держать в голове, чтобы писать на языке, решая конкретные бизнес задачи как full-stack разработчик, а не воображаемые проблемы в стиле «ой, у меня тут инкапсуляция нарушена, кто-то потом, используя мой код, сможет выстрелить себе в ногу».
Но что меня больше всего всегда выводило в С++, даже когда я только на нем и писал, это, разумеется стандартная библиотека. Написанная не для того, чтобы ее использовали. А как будто, чтобы показать всем: «Смотри, как я могу!»,- как ребенок в песочнице. Которая задала целый тренд мышлению С++ программистов совершенно не в том направлении, породив еще более форменное уродство под названием boost. И когда появился Qt — с человеческими интерфейсами (я, разумеется, не имею в виду UI, я имею в виду интерфейсы библиотеки), написанный для людей, он уже на этот тренд никак особо не повлиял.
Поэтому развивается С++ семимильными шагами или не развивается, мне как-то совершенно наплевать. Если придется возвращаться к программированию, где нужно думать не только об алгоритмической, но и других видах оптимизаций, я определенно начну учить Rust. Или тот же C#, если его допилили за эти годы. Но никак не в плюсы.
нужно начать, а не плакать об упущенных возможностях…

тогда это,… кругозор появится
Начать что?
Благодаря тому, что я выучил что-то совсем другое и избавился от ощущения, что С++ это центр вселенной, я работаю на заказчиков по всему миру, и я очень доволен. Уровень заработков у меня возрос в несколько раз. Где упущенные возможности-то? :)
А в javascript вдруг оказалось, что 90% всех моих логических задач решает то, что функция — это одновременно класс, объект, замыкание и экземпляр. То есть всего одна гибкая языковая конструкция решает все задачи.

Только вы забыли упомянуть цену этого.

Добавьте к этому async/await для «многопоточности», для понимания которой кроме этих двух слов ничего не нужно.

Ну еще бы, ведь к многопоточности это не имеет абсолютно никакого отношения. Расскажите мне, пожалуйста, как с помощью async/await распараллелить вычислительную задачу.
Только вы забыли упомянуть цену этого.

Да очень просто цена считается. Вот есть компания, ей нужно обеспечить бизнес процесс для сотрудников. Ее интерес — чтобы сотрудники имели заданный интерфейс взаимодействия друг с другом, чтобы работать эффективно, не тратить кучу времени на пересылку емейлов туда-сюда и иметь безопасный доступ к данным, ведь большая часть из них — еще и фрилансеры (переводчики, корректоры и т.п.). А еще хорошо бы знать, чем они там занимаются.
Для компании делается веб приложение. AWS бэкенд для него, при порядка 100 сотрудников в системе, обходится в 200$ в месяц, из них большинство уходит на базу данных. Ключевой для Вас момент — вычисления в Lambda на javascript — забирают 15$. Фронт энд запускается на любом обычном компьютере в браузере — это все что волнует компанию об его эффективности.
Разумеется, в такой ситуации самое дорогое для компании — это зарплата разработчика и скорость разработки. Поэтому на С++ такое никто не делает (хотя вроде ничего не мешало сделать в Lambda поддержку С++, это же чистые вычисления! Но нет же — с удивлением обнаруживаем там только Java, Go, PowerShell, Node.js, C#, Python и Ruby).
Ну еще бы, ведь к многопоточности это не имеет абсолютно никакого отношения. Расскажите мне, пожалуйста, как с помощью async/await распараллелить вычислительную задачу.

Вроде специально многопоточность в кавычки взял, нет, не помогло. Да, физически это к многопоточности не имеет ни малейшего отношения. А как часто Вам нужна именно физическая многопоточность? Чаще всего нужна многопоточность логическая — вот сейчас мне нужно делать А и Б одновременно, и чтобы ни одно из них не зависило от другого. async/await — это оно и есть. А вот как раз вычислительная задача с точки зрения конечного пользователя — это что-то неделимое, логически ему нужен просто конечный результат.

.Для компании делается веб приложение

Веб-приложениями мир не ограничивается. У вас, так сказать, та же болезнь, что и раньше, только наоборот — раньше вы считали, что на C++ нужно писать все, теперь вы считаете, что на нем не нужно писать ничего :) Вас просто кидает из крайности в крайность.

.Вроде специально многопоточность в кавычки взял, нет, не помогло.

Потому что async/await относятся к асинхронному выполнению, а не к многопоточности. Употребляйте термины правильно.

.А как часто Вам нужна именно физическая многопоточности?

Регулярно. Я-то не веб-приложения пишу. Каждой задаче — свой инструмент.
раньше вы считали, что на C++ нужно писать все, теперь вы считаете, что на нем не нужно писать ничего

Где я такое писал?
Я написал, что лично я постараюсь к С++ больше никогда не возвращаться. Как и к embedded. Хотя это мои личные пристрастия, я все равно подробно написал, почему для меня это так. Я совершенно четко понимаю, что в мире миллионы С++ разработчиков, триллионы legacy кода на С++, и ни сегодня ни завтра это никуда не денется. Так же как кучи процессоров и RTOS систем, для которых есть только С библиотеки, кучи графических и игровых движков и т.п. Но я считаю, что это потому, что так исторически сложилось, а не потому, что С++ лучше альтернатив. Если бы сейчас я выбирал язык под тот же круг задач, что я выполнял раньше (разработка управляющих программ для научных лазеров, например), я бы всеми силами постарался избежать использования С++, если это от меня зависит, и учил бы Rust. например.

Что в своем оригинальном сообщении я считаю реальностью, общей для всех — это полная ущербность стандартной библиотеки, которая сильно испортила общее направление развития языка. Я просто в принципе не вижу задач, для которых ее можно использовать (ну, разумеется, кроме поддержки legacy, где она уже используется). Если у вас есть нет сильного ограничения по ресурсам, и важно время разработки — Qt и подобное гораздо лучше. Если есть ограничения по ресурсам (например, embedded), то ее опять нельзя использовать, потому что исключения — это непозволительная роскошь. В итоге тысячи проектов, где люди пишут с нуля свои собственные контейнеры, функциональщину и прочее.