![](https://habrastorage.org/webt/ud/4s/-_/ud4s-_jhcan8lv7ei9kfabnsszo.jpeg)
Всем известно, что нет ничего глупее споров «какой язык лучше». Например, лучше для чего? Разные языки успешны в разных нишах — и бессмысленно делать категоричные выводы, не учитывая это.
Но что получится, если обратиться к опытным специалистам, которые сами всё это понимают, и попросить их всё-таки устроить холивар «C++ vs C#»? Оказывается, можно узнать много любопытных деталей. Слово «кроссплатформенный» можно по-своему применить к обоим языкам, но что это значит на практике? Активно ли сейчас развивается С++? Ломал ли C# когда-либо обратную совместимость? Ответы могут быть очевидны для тех, кто уже глубоко погружён в оба языка сразу, но таких людей немного — а все остальные узнают что-то новое.
Со стороны C++ поучаствовал Сергей sermp Платонов — председатель программного комитета конференции C++ Russia. Сторону C# представлял Анатолий Кулаков — он входит и в ПК конференции DotNext, и в число лидеров DotNetRu. А ведущим дискуссии, в жизни которого сосуществуют оба этих мира, стал Дмитрий mezastel Нестерук.
![](https://habrastorage.org/webt/sn/rb/_i/snrb_ie2-dnmplhnbfnl_klnvca.jpeg)
Дмитрий: Добрый день, коллеги. Добро пожаловать на неформальные посиделки на тему языков программирования. В интернете нам постоянно напоминают, что сравнивать языки нельзя. И сегодня мы займёмся именно тем, что делать нельзя: сравним С++ с C# и .NET, их плюсы и минусы. Представьтесь, пожалуйста.
Анатолий: Меня зовут Анатолий, и я сегодня буду топить за C#, потому что я занимаюсь этим языком с первых его версий и, кажется, знаю о нём всё.
Сергей: Привет, меня зовут Сергей, я сегодня буду топить за C++. Дима правильно сказал, что сравним плюсы и минусы. «Плюсами» все называют известно что, получается, что C# в данной дискуссии будет минусом. Правильно, Анатолий?
Анатолий: У C# на два плюса больше! Поэтому я думаю, что это эволюционное развитие плюсов, которые уже морально устарели и не способны конкурировать практически нигде.
![](https://habrastorage.org/webt/_p/wy/sj/_pwysj2lxe1ncg6lmuzqxfs2dg0.jpeg)
Образование
Дмитрий: У меня первый топик для нашей дискуссии. Представьте, что в университет приходят новые студенты, им нужен первый язык. Как вы считаете, каким должен быть первый язык, который люди получают на первом курсе: C++, C# или вообще ассемблер?
Сергей: Я какое-то время преподавал, поэтому у меня есть устоявшееся мнение. Понимаю, что мы здесь собрались дискутировать, какой язык лучше, и я выступаю за C++… Но для обучения C++ нужно понимать архитектуру компьютера. И с этим большая проблема преподавания у студентов (по крайней мере, в том вузе, где я преподавал). А чтобы преподавать алгоритмы и прочее, наверное, надо что-то, что не акцентирует внимание на инфраструктуре, на самом языке. Вот Eiffel был попыткой сделать такое, но там тоже много магии. Поэтому я бы сказал, что из двух наших языков ни тот, ни другой не подходят.
Программирование — оно разное, и преподают не «программирование», а алгоритмы, структуры данных и так далее. Возможно, что имеет смысл на каждом предмете выбирать свой инструмент. По какому-нибудь Lisp разбираться со структурами данных. А C++, соответственно, давать уже после того, как студенты поймут что-то про архитектуру. И тогда можно будет понять, зачем вся эта боль и страдание. Я даже не стану спорить с тем, что плюсы — это про боль.
Анатолий: Да, я полностью согласен, что нужно разделять предметы, а не ставить это в «программирование» и одним языком всё забивать. Но если вы дойдёте до уровня, когда изучили базисы, основы, алгоритмы, и начинаете выбирать какой-то промышленный язык, то здесь, безусловно, C# будет намного лучше. Потому что он вас не заставляет учить всю эту муть на уровне архитектур, байтов памяти и прочих «закатов солнца вручную». Он даёт сразу понятный язык, простой синтаксис, и на этом языке уже с первого-второго курса можно зарабатывать вполне осязаемые деньги.
Дмитрий: Тут есть аргумент, что не давать начинающим студентам некоторые вещи вроде указателей — это какое-то кощунство. У них будет огромная дыра, если человек не понимает, что, допустим, ссылка — это на самом деле всего лишь адрес переменной в памяти. Что вы думаете по этому поводу?
Анатолий: 20 лет назад это было актуально, когда у компьютеров было недостаточно памяти, не хватало дисков и прочего. А сейчас посмотри на этих джаваскриптеров, они на каждый «hello world» притаскивают по 500 мегабайт библиотек. Сколько они занимают в памяти? Какая у них производительность? Какие там ссылки? Да никого это не волнует. Главное — это быстренько набацать и выпустить что-то в продакшн. Я не утверждаю, что это хороший или правильный путь, я утверждаю, что нужно меняться вместе с реалиями. Может быть, сейчас уже не настолько важно, сколько у тебя занимает ссылка.
Сергей: Наверное, смотря где. Дмитрий, насколько понимаю, интересовался алгоритмическим трейдингом — живо представляю, как он подтягивает библиотеки на JS, чтобы отправить заказ на биржу.
Дмитрий: Ну да, естественно, на практике там никто не использует языки такого типа. Хотя теоретически это, может, и возможно: не будем забывать, что в инфраструктуру JS вбрасываются неслабые деньги. Движки, которые делают компиляцию JS во всё и вся. Многие рассматривают этот язык как first-class language для всего вообще.
Естественно, что алготрейдинг — это сейчас удалённая от подобного дисциплина, но алготрейдинг и в целом финансовая математика — это вообще специфичная область. В ней как раз преобладает C++. И преобладает он отчасти из-за инертности, просто из-за исторических причин: в начале все были на С++, а область эта консервативная.
Сергей: Не соглашусь. Я сейчас работаю в финтехе, и коллеги, которые тут с самого начала алготрейдинга, рассказывают про крупные компании, которые сначала писали на Java. Поначалу Java справлялась с алготрейдингом, но, когда рынок стал расти и появились конкуренты с C++, они в какой-то момент просто не справились, не успели всё сделать эффективно… Так что не все в алготрейдинге начинали с C++. Просто те, кто не писал на нём, умерли. Такой естественный отбор.
Дмитрий: На самом деле можно брать шире. Известно очень много примеров, когда даже крупные банки держат свои алгоритмы в экселевском документе. Они потом используют Excel ещё и как сервер, чтобы всё это обсчитывать. Там адские тормоза, но всё зависит от того, делаешь ли ты high-frequency trading (или вообще что-то высокочастотное). Если ты market maker — естественно, что тебе нужна высокая производительность, и там дело даже не ограничивается С++, там мы уходим в железо и HDL-языки.
Но наша дискуссия не только вокруг алготрейдинга, а вокруг простых вещей тоже. Вот я приведу такой пример. Мне нужно было в связи со строительством написать несколько маленьких приложений, рассчитывающих разные вещи: например, как класть кирпичи вокруг контура дома. И я практически не представляю себе, как делать такие вещи на C++, потому что всё, что связано с UI, там слабее. Есть всего один фреймворк, Qt, и даже на нём писать очень тяжело. А если я сажусь за C#, за WinForms, то просто моментально делаю приложение.
Анатолий: Ну, визуальная часть всегда являлась сильной стороной C#. Microsoft много вкладывался и в формочки, и даже в кроссплатформенные формочки, и в целом в визуализацию. Поэтому, если мы говорим о визуальных десктопных приложениях, то мне кажется, плюсы вообще далеко-далеко позади.
Сергей: Ну, it depends, как всегда. Я UI очень не люблю, но на плюсах мне постоянно приходится его делать. Казалось бы, притащи JS и просто взаимодействуй с плюсами. Но я работал с embedded, и там это тяжело. Люди покупали какой-то быстрый дорогой движок, но он всё равно не справлялся с нормальным рендерингом UI, написанного на JS. А переписав всё это на Qt, получалось разогнать. Обыкновенная история.
![](https://habrastorage.org/webt/kc/9t/uf/kc9tufwhjjwnla-uga_j8abdwqg.jpeg)
Кроссплатформенность vs кроссплатформенность
Сергей: Я тут хотел уточнить. Я про C# мало знаю, сам трогал его очень давно, в самых первых версиях (мне тогда ещё обратную совместимость сломали). Поэтому вопрос: а его до сих пор развивает только Microsoft?
Анатолий: Нет, сейчас он кроссплатформенный, открыт и заверифицирован под ISO (ECMA-334 и ISO/IEC 23270). Кстати, насколько знаю, у С++ до сих пор нет открытой ISO-спецификации, только платная. А C#, в отличие от этого, полностью открытый. Развивается многими компаниями (в их числе Google, Amazon и Samsung), у нас есть .NET Foundation. Я даже не знаю сейчас более открытого языка, чем С# и платформа его .NET.
Сергей: Ну, Haskell.
Анатолий: Кстати, автор Haskell работает в Microsoft Research и приложил немало усилий, чтобы в C# появились всякие клёвые штуки — например, статическая проверка, какая-нибудь рефлексия, о чём плюсы, вероятно, и мечтать не могут.
Сергей: Мечтать-то могут, и даже идёт работа в эту сторону. Но понятно, что у всего есть своя цена. В C++ просто отказываются платить эту цену.
Анатолий: Какую? Они компилируются по два часа, какая ещё может быть цена?
Сергей: В C++ принцип zero cost abstraction. Ну то есть виртуальная машина — это не zero cost abstraction, правильно? Приходится с этим мириться.
Дмитрий: Ну, зато виртуальная машина может, например, затюнить код для той или иной архитектуры. В то время как на С++, если использую AVX-инструкцию на компьютере без AVX, у меня процесс просто накрывается. Я бы сказал, что этот аргумент не совсем корректен, потому что теоретически — я подчеркну, теоретически — JIT может делать то, что C++ недоступно. А именно оптимизацию в момент запуска.
Сергей: Но в C++ во время компиляции ты можешь полностью контролировать, какие инструкции тебе нужны. В данном случае не руками управляешь, а инструменту (компилятору) отдаёшь на откуп. Вот смотри, какие инструкции есть на этой архитектуре, какой набор инструкций…
Дмитрий: Это понятно. Но можно сформулировать так: поскольку платформ миллион, мы никогда не получим какой-то идеал, потому что мы не можем релизить миллион версий с разными компиляционными флагами. Правильно? Мы выпускаем обычно x86 и x64, а не разбиваем всё это на какие-то подгруппы.
Сергей: Почему не можем? XXI век. Держи Docker с разными параметрами, и всё.
Дмитрий: Когда у нас есть конечный клиент, который скачивает наше приложение, он хочет скачать конкретный бинарник. И в этом бинарнике лучшее, что мы можем сделать — это натыкать везде if. Типа «if cpuid такой-то и поддержка avx такая-то, тогда используем версию алгоритма 25». В результате нам нужно 25 разных версий одного и того же алгоритма, потому что ускорение зависит от платформ, оно platform-dependent.
Сергей: Наверное, согласен. Просто я, если честно, ни разу не создавал не-внутренний продукт. Я в основном в компаниях, которые сами используют свой продукт.
Дмитрий: Ну, конечно, самый лучший вариант, когда ты предсказуемо знаешь архитектуру. В этом случае, строго говоря, вообще никто не заставляет тебя использовать x86-инструкции. Можешь брать конкретную карточку (например, Nvidia Tesla) и делать всё, что хочешь. Это и мой подход тоже, я контролирую свою архитектуру. Но когда ты делаешь mass-market решения для пользователя… Если взять какой-нибудь условный ReSharper, он не может просто взять и использовать GPU-ускорение для каких-нибудь произвольных индексов. Потому что GPU-ускорение — это не портативная штука.
Сергей: На самом деле есть подходы (сейчас в детали, наверное, вдаваться не нужно), есть интересные ребята (автор подхода, кажется, сейчас тоже в Microsoft перешёл). Вот у нас на конференции в позапрошлом году был доклад про то, как бы написать такую программу, которая сама будет разбираться, что где (относительно легко, опять же zero cost abstractions). Чтобы на лету можно было выбирать, и если что, грамотно перестраивать код в CUDA-стиль…
Дмитрий: На самом деле CUDA сама пытается решить эту проблему, потому что в CUDA есть некий промежуточный слой PTX, который этим занимается. Но это пока всё очень тяжело, потому что железо кардинально меняется эволюционно, и очень сложно за этим вообще поспевать. И если мы посмотрим на использование GPU-ускорения, например, в продуктах Adobe, то они используют очень узкий срез имеющихся технологий. Если у тебя карточка правильная — то да, всё будет. Но если она чуть-чуть экзотическая — в этом плане уже не гарантировано ничего.
Анатолий: В этой дискуссии мы затронули довольно важную тему, такой миф: C++ декларировался много лет назад как такой кроссплатформенный язык, но на данный момент кроссплатформенности куда больше в C#. Один-единственный бинарник, работает везде, где поддерживается .NET, а это практически везде.
Сергей: Ну, это тоже достаточно голословно. Я как человек, большую часть жизни проведший в embedded, редко видел, чтобы .NET поддерживался тулчейном производителя железа. Компании, которые производят железо, берут тот же G++ или Clang или делают так, чтобы он начинал генерировать код для их платформы.
Дмитрий: Да, но проблема в том, что каждый раз, когда они это делают, они теряют что-то из С++. Например, Nokia использовала вариацию C++, но их C++ был с безумными наворотами и безумным API, которое всех бесило. То есть это не просто С++, а С++ под ту или иную платформу. И тогда начинаются проблемы. Например, взять ту же CUDA. Она как бы должна плюсы просто через себя пропускать, она вообще не компилятор, а просто драйвер. Но несмотря на это, у неё бывают затыки с тем, что она всё-таки использует какой-то фреймворк для раздирания CUDA-файлов на GPU- и CPU-части. И иногда у неё это не получается.
Сергей: Я немножко не это имел в виду. Просто, когда я слышу, что «.NET везде запускается», большая часть моей рабочей биографии взбрыкивается. Когда ты покупаешь железку с кастомным процессором, она просто идёт в комплекте с поставкой G++. И там обыкновенный C++, который G++ из тулчейна умеет преобразовывать в машинный код, поддерживаемый именно этим процессором.
Дмитрий: Но это опять надо пересобирать…
Сергей: Конечно.
Дмитрий: И идея, что мы берём уже существующий плюсовый код и втаскиваем его на железку — эта идея тоже не работает, потому что внезапно ты втащил свой обычный x86 куда-то, где у тебя 8 гигабайт памяти на всё про всё, и уже не развернуться: например, нет свопа на диск, потому что нет диска и доступа к нему. Это если мы про портативность. Зависит от целей, естественно.
Анатолий: Плюсы работают на большем количестве устройств, и, безусловно, embedded — это одна из сильнейших частей. Но обычно придётся как-то под платформу свой код адаптировать. Вот это плохо. Я могу одним кодом накрыть огромное число платформ, архитектур, моделей. На плюсах мне приходилось думать о каждой отдельной платформе: а где он там запустится, а при каких условиях. И это очень плохо, это очень сдерживает.
![](https://habrastorage.org/webt/f1/wn/1z/f1wn1zxi80gplsj3bpidl9fpr1i.jpeg)
Стабильность, совместимость, развитие языка
Дмитрий: Ещё были упомянуты zero cost abstractions, но проблема в том, что у этого огромная цена. Например, в .NET есть понятие перечисляемого типа и интерфейс IEnumerable. И у каждого типа, например, массива, можно взять и проходить по итератору. А в C++ такой идеи нет. Из-за zero cost abstraction, чтобы обойти коллекцию, есть пара begin() и end(), есть правила их работы, и всё это намного сложнее (особенно для тех, кто начинает программировать). Это прямо проблема: как обойти какой-нибудь массив «от А до Я».
Сергей: Если я правильно понимаю, о чём вы говорите… Если просто нужно обойти какой-то контейнер от начала до конца, то сейчас просто пишешь, как в каком-нибудь Питоне.
Дмитрий: Это всё прекрасно. Но у тебя, например, нет использования полиморфизма для этого. Ты не можешь сказать, что вот у меня функция, которая получает некое значение, которое является перечисляемым априори. Ты не можешь сказать, что вот у меня есть значение, которое реализует интерфейс, и вот в этом интерфейсе есть итератор, например.
Сергей: Мы говорим про какой C++? Про C++ вообще, C++ будущего, С++, который сейчас принимают в стандарт?
Дмитрий: Ну, если в плюсах будущего это будет…
Сергей: В C++20 это уже есть. Уже можно сказать, уже можно самому даже объявлять. Это не интерфейсы, но, как правильно сказать… В общем, можешь объявить, что у тебя тип должен удовлетворять таким-то условиям. Например, у него begin и end, которые возвращают итератор. А итератор — это в стандартной библиотеке такой подготовленный концепт. Он говорит, что это такое, описывает. Итераторы тоже разные бывают. В общем, стараемся, делаем так, чтобы людям было удобнее.
Дмитрий: Мне кажется, это выросло из того, что люди просто поняли, что без концепций итерируемости объекта жить тяжело. Потому что непонятно, как писать обобщённые вещи. Да, zero cost abstraction означает, что у нас нет затрат на хождение по v-table при поиске… В .NET есть просто конкретный метод, например. И нам, чтобы его найти, естественно, приходится затратить усилия, от которых плюсы отказываются. Но с точки зрения юзабельности всё-таки конечный результат не такой хороший, я бы сказал.
Сергей: Естественно, должен быть баланс. Нельзя иметь всё и сразу.
Анатолий: Это заставляет задуматься: сколько лет прошло. Альтернативные языки развиваются, и в них такие базовые вещи появляются с самого начала. Сейчас они догоняют что-то более существенное и интересное. А плюсовики сидят по десять лет с одним и тем же непонятным синтаксисом, непонятными абстракциями, непонятными костылями и слабо развиваются. Можно это поставить как один из минусов.
Сергей: Ну come on! Что значит «слабо развивается»?
Ты упоминал комитет — у C++ тоже есть комитет ISO, который его развивает. Там есть представители в том числе Microsoft, которые сильно топят за то, что «нельзя такое делать, потому что у нас куча легаси, которое нам надо поддерживать». Просто C++ — это язык уже состоявшийся. И, естественно, очень аккуратно шагает. Одна из главных задач (что было декларировано ещё Страуструпом при создании) — это совместимость с C. Но сейчас C уже даже развился достаточно далеко, приходится обозначать, с каким именно C совместимость.
И на мой взгляд, сейчас C++ развивается огромными темпами. По поводу концептов и так далее — на самом деле всё растёт, конечно, не из итерируемости. На самом деле развитие идёт по тому, что описал ещё Александр Степанов — один из авторов того, что мы сейчас называем «обобщённое программирование», тот человек, который фактически втащил в C++ шаблоны, дженерики и так далее. Если честно, не знаю, насколько именно комитет вдохновляется этими идеями, но мне кажется, что какое-то пересечение с ними точно есть.
Анатолий: Кажется, что все эти метаклассы, итераторы — это реально вдохновение, которое было уже много десятков лет назад. Даже если метапрограммирование взять, шаблоны, макросы — это же всё люди давно пережили, перемололи, и существуют намного более простые, очевидные, понятные концепции. В других языках это всё сделано в миллион раз лучше и быстрее, с типобезопасностью, проверкой в compile time и так далее.
Сергей: Подожди, ты уже говоришь про то, за что не все готовы платить. Я не хочу, чтобы моя программа что-то проверяла в compile time без моего ведома. Понимаешь?
Анатолий: Я думаю, это всё флажочками можно настроить. Уровень оптимизации ставишь, и она тебе или проверяет, или нет. Это не проблема.
Сергей: Часто нужно контролировать всё руками. Точно знать, что происходит. Потому что инструменты — ну такое.
Дмитрий: Тут даже не про инструменты. Тут тот факт, что языки вроде D и Rust, допустим, говорят: ну вот да, есть такая фишка, что когда доступ к элементу массива, можно его проверять, а можно не проверять. И они просто отдают это на откуп пользователя, то есть ты можешь сказать «а давайте отключим проверки массивов», «а давайте включим». То есть контроль какой-то в этом плане.
Сергей: Непонятно тогда, когда у тебя Unsafe и Safe есть, как в Rust, я не вижу разницы с C, например, в таком случае.
Анатолий: Разница в том, что ты можешь писать безопасно, а можешь писать быстро. А в C ты вынужден писать опасно. Ну, да, может быть, быстро. Иногда намного важнее стабильность продукта, чем быстрота.
Дмитрий: На самом деле, если уж мы начнём копать вот тему с новыми языками, в С++ есть такие вещи, которые вообще очень тяжело донести до людей. Простой вопрос: какого размера int? В большинстве языков ты знаешь ответ на этот вопрос. Ты говоришь: int — это 32 бита. А в плюсах не знаешь. Ты знаешь размер на своём конкретном компьютере, потому что запомнил, но, строго говоря, даже базовые типы не хочется использовать, потому что они недетерминированные. И вот меня бесят такие вещи, когда есть набор легаси-подходов вроде того, что int будет разным на разных платформах. И сейчас-то мы уже понимаем, что так делать нельзя. Почему бы не шагнуть дальше этого и как-то решить эту проблему?
Сергей: Ну, это решено. Есть STD, нужные типы с фиксированной длиной. Сейчас представитель России в комитете втаскивает int переменной длины (ну опять же, с zero cost abstraction).
Анатолий: А я правильно помню, что там даже недетерминированный размер указателя на метод? То есть под разные компиляторы и разные платформы указатели разные?
Сергей: Естественно, это архитектура. Когда ты близко к железу, как ты можешь гарантировать размер указателя, если ты то на 8-битной, то на 64-битной?
Анатолий: И как можно после этого какую-то арифметику на указателях делать? Это же с ума сойти.
Сергей: В смысле? Ну, аккуратно.
Анатолий: Понятно. Подход везде понятен, аккуратно, ручками контролируя всё.
Сергей: Ну да. Опять же, в современных стандартах C++ развиты подходы… Если говорить о выборе, то в современных плюсах, по сути, есть выбор, использовать ли сборщик мусора. Просто GC там построен на reference counter-ах.
Вообще, по вашим словам, коллеги, я, простите, чувствую, что вы давно не обновляли знания про современные плюсы.
Сейчас от людей вроде Страуструпа, входящих в пантеон плюсовых богов, исходит много призывов разобраться с тем, как преподавать современный C++. Проблема в том, что люди думают в категориях C++ 2003 года, и преподают в этих же категориях. И в связи с этим есть интересные новые проекты и подходы, есть современные курсы — скажем, ребята из Яндекса сделали прекрасный курс. И сейчас в плюсах считается моветоном, например, использовать чистые new и delete.
Дмитрий: Насчёт твоего комментария про обновление знаний… Нюанс в том, что мой подход, например — использовать маленькую дельту C++, которая у меня гарантированно работает и с которой я «дружу». Понимаешь, C++ обширен. Есть шаблонное метапрограммирование, и всё бы хорошо, там много магии, но, к сожалению, эта магия нечитабельная. Это код, в котором не-автору без каких-то особых знаний не разобраться, в каком-то смысле чёрный ящик. И вот таких чёрных ящиков в плюсах много, таких областей тьмы, которые не переварить… Хочется, чтобы, не знаю, твой опцион обсчитывался предсказуемо, хорошо и без каких-либо ухищрений.
Самый простой пример — разговор про ranges (range-v3 и вся эта тема). С одной стороны, всё это здорово: появляются вещи, которые в C# уже были несколько лет, позволяющие, например, построить календарик путём всяких преобразований стандартной коллекции. С другой стороны, то, как это реализовано в С++, просто неприятно по сравнению с C#: оно тяжело, неудобочитаемо.
Сергей: Это вкусовщина. Мне, наоборот, нравится. Я так понимаю, ты к докладу Ниблера и его представлению…
Дмитрий: Понимаешь, когда для фильтрации коллекции используется оператор «или», у меня сразу к этому вопросы. И C#, и Java всё сделали через точку, через обычные методы.
Сергей: А мне кажется, это вдохновлено Bash'ем. То есть это просто pipe.
Дмитрий: Ну, да, наверное, это объясняет что-то в этом подходе.
Сергей: Многое объясняет! Давайте вот про PowerShell поговорим, раз заговорили про Bash. Кто видел PowerShell?
Анатолий: Я пишу на PowerShell, шикарный язык. Но опять же, pipe нужно вставлять там, где он к месту, там, где вся архитектура им пронизана. Не там, где тебе нужно сделать какое-то одно действие, и оно здесь идиоматически плохой синтаксис.
Сергей: В range'ах pipe как раз очень…
Дмитрий: В range они используются, по-моему, по следующей причине… Скажу так: если бы в C++ были extension-методы или extension-функции, использовали бы их, конечно. Потому что самое естественное, если вам нужно отсортировать коллекцию — это написать «коллекция.фильтр()». А не «коллекция | view:: фильтр()».
Анатолий: У меня тоже сложилось такое впечатление, что тебе 20 лет стреляли в ноги, били по лицу, стучали головой о стену, а потом в конце концов говорят: «Ну вот мы теперь всё сделали красиво в 20-м стандарте, давайте теперь учить плюсы правильно». Да уже никто не хочет их учить правильно! То есть это боль многолетняя.
Сергей: Пожалуйста, не учите. В чём проблема? Пишите на C# — торгуйте на нём, пишите embedded. Я не против.
Анатолий: Ну, есть узкие ниши, где плюсы всё ещё остались.
Сергей: Embedded — «узкая ниша»… Я прямо сейчас, глядя у себя на кухне по сторонам, вижу кучу компьютеров.
Дмитрий: Я каждый раз, когда лечу на самолёте, думаю: «Блин, надеюсь, эти плюсовики хорошо всё там написали».
Сергей: Ну, кстати, там в основном Ada, насколько я помню.
Дмитрий: Ada там доминирует, да.
Анатолий: Мне, кстати, недавно попалась отличная статейка, где автор на разных языках (около 10) написал низкоуровневый драйвер — network driver для 10-гигабитной карточки Intel. От C до Swift, JS, Python и, естественно, C#. Если мы посмотрим на эти графики, которые у него получились, то C# на больших батчах (когда нивелируются расходы на запуск) идёт вровень с C и Rust.
![](https://habrastorage.org/webt/bk/bp/ur/bkbpuriesi98tzgy1eon4cek8vs.png)
То есть, если мы говорим о производительности, может быть заблуждением, что C# очень сильно где-то уступает. Есть ещё обалденный доклад Федерико Луиса Scratched Metal, где он показывал, как оптимизировал C#-код под процессорные профайлеры.
Сергей: Ну это опять начинается. Штука в том, что когда ты начинаешь оптимизировать что Java, что C#, становится непонятно, почему не писать на плюсах. Потому что тебе нужны специфичные знания. И, как мне кажется, нивелируется преимущество языков вроде C# и Java — не очень высокий порог входа. Насколько понимаю, как раз то, про что Дмитрий говорил: про читаемость кода, что учить много, тяжело объяснять какие-то концепции и так далее.
Анатолий: Я на работе 99% времени пишу на «нормальном» С# — безопасном, стабильном и всё время работающем. А 1% времени я хочу написать какой-то быстрый низкоуровневый код. И это C# мне тоже позволяет. Но основной мой инструмент — это всё-таки стабильный, читабельный, без ошибок…
Дмитрий: Толя, давай я приведу тебе простой пример: векторизация. С векторизацией в .NET всё очень плохо, несмотря на то, что медленно пилится System.Numerics.Vectors. И к чему это приводит, с моей стороны, например? К тому, что если суёшься на рынок и покупаешь математическую библиотечку для .NET, она написана на плюсах (с дотнетной обёрточкой). Потому что в .NET нет практически никакого доступа к аппаратному ускорению (AVX и прочее), это сейчас на каком-то зачаточном этапе.
Анатолий: В .NET Core 3 вышли интринсики, где можно напрямую обращаться к AVX. Они там действительно в зачаточном состоянии, но базовые вещи есть, а остальное вполне двигается.
Дмитрий: Ты понимаешь, у нас 2019 год на дворе. Я как пользователь всего этого математического ускоренного добра не дождался этого. И в результате для меня, если хочу что-то быстро считать, C# уже не кандидат. Потому что библиотеки на C++ уже есть. Может, уже время упущено для этого.
Анатолий: Мне кажется, что C# движется в сторону плюсов, он пытается отвоевать их рынок. А вот плюсы уже не движутся никуда.
Сергей: Откуда это? Что значит «плюсы не движутся никуда»?
Анатолий: Когда мне в 2019 году рассказывают, что в будут стандарте будут итераторы, будут какие-то подвижки насчёт лямбд, мне кажется, что…
Сергей: Я не знаю, зачем ты разговариваешь про итераторы и лямбды, не понял, в чью сторону был камень…
Анатолий: Не про итераторы, я неправильно выразился, я имел в виду enumerable'ные контейнеры, которые мы до этого обсуждали. А у нас тем временем появился pattern matching.
Сергей: Всё зависит от того, надо это или нет. У нас pattern matching обсуждают. Но пока нет всех аргументов, нужен ли он именно в плюсах.
Дмитрий: Я слышу много подобных комментариев от плюсовиков, которые говорят, что «хотя уже есть очевидное присутствие того или иного подхода в других языках, он уже отработан, люди его любят и строят на нём решения, мы всё равно не хотим это в плюсах, потому что это не идиоматично плюсам». И мне кажется, что Java попала в ту же дыру. Java сказала «нет, ребята, у нас делегатов не будет». И в Java до сих пор нет понятия делегатов, а в .NET всё это прекрасно работает.
Сергей: Смотри, в плюсах всё очень просто. Опять же, возвращаемся к комитету. Там есть верхушка — это люди, которые занимаются разработкой компиляторов. И для них слова «zero cost abstraction» — это как раз то, чем они должны руководствоваться. И словом «legacy», к сожалению.
Дмитрий: Ну, zero cost abstraction — это ассемблер. Если мы хотим вообще zero cost abstraction, надо писать всё на ассемблере.
Сергей: Там нет abstraction.
Дмитрий: Ассемблер — это абстракция над бинарным кодом. Просто это второе поколение, а не третье.
Сергей: Так вот, про всякие «удобные штуки» оказывается, что непонятно, как заставить их быстро работать.
Дмитрий: Пускай они работают медленнее. Идея с асинхронными итераторами, корутины, всё вот это — в .NET с C# ключевое слово yield уже не знаю сколько релизов прекрасно работает. Да, за кулисами строятся огромные стейт-машины, прям магия. Но и в async/await строится магия, и в итераторах. Но все этим пользуются, и это реально удобно.
Сергей: Корутины и в плюсы добавляют, здравствуйте.
Дмитрий: Ну да, прогресс идёт. Но корутины появляются сейчас, а не 10 лет назад.
Сергей: Ещё раз. Плюсы старше, и на мой взгляд, скорость развития падает с накоплением кодовой базы. Понятно, всё зависит от того, есть ли желание сохранять поддержку легаси. Для плюсов это принципиальная позиция. То есть код, который ты написал в 80-х, сейчас скомпилируешь современным компилятором.
Дмитрий: Да, но код, который ты написал на C# 1.0, ты тоже скомпилируешь современным компилятором.
Сергей: Это неправда. Я в самом начале дискуссии сказал, что у меня на ранних версиях .NET прилетело обновление, и внезапно все программы перестали работать.
Дмитрий: Возможно, просто поменялось API, которые ты использовал. Тут нужно разделять библиотеки и язык программирования.
Сергей: У меня ничего не было, просто C#. Я был молодой, это были первые годы.
Дмитрий: Я помню только один breaking change, в C# 4 — изменение поведения foreach чуть-чуть. Конечно, в версиях 1.x всё могло быть более турбулентно, но сейчас мы точно не в такой фазе, когда кто-то что-то внезапно ломает.
Анатолий: Ну и официально Microsoft придерживается позиции, что строго следит за обратной совместимостью, они тестируют новые версии на огромном количестве машин и кодовых баз. Возможно, у тебя был баг или что-то в этом духе.
Дмитрий: В общем, в .NET тоже следят за обратной совместимостью, но скорость прогресса обскакала и C++, и Java.
Сергей: Мне кажется, сыграло большую роль, что вначале всё это драйвила одна компания. Потому что C++ изначально в комитете — а это политика, каждый пытается протащить своё решение, и это как заседание Сената в «Звёздных войнах».
Дмитрий: То есть твой аргумент в том, что мы все заложники комитетов, которыми движет не инновация?
Сергей: Проблема в том, что не выбрать решение, которое удовлетворит всех. Инструмент настолько широко разошёлся, что его использует очень много компаний. Ты те же корутины вспомнил: почему их приняли поздно? Потому что Microsoft, кажется, с Google не мог договориться. Были две имплементации — я не помню, кто был за stackful, а кто за stackless, но не могли договориться. Потому что обе компании большие, у них огромные кодовые базы, которые уже содержат решение, и они отказываются это переписывать.
Дмитрий: С точки зрения читателя создастся ощущение, что на него плевали с высокой колокольни, потому что есть corporate interests, они занимаются там междусобойчиками, а вас всё это как бы и не касается — идите, холопы, «let them eat cake».
Сергей: Всё как раз наоборот. Комитет пытается выбрать так, чтобы обыкновенному человеку не пришлось страдать. И часто это тяжело.
Дмитрий: Ну, я за себя могу сказать, что не буду страдать, если где-то пропадёт прям zero cost, зато появится какая-нибудь гибкая возможность ходить по бинарному дереву и делать итерирование разными способами без временных переменных. Если внезапно появилось ключевое слово yield, которое за собой тащит стейт-машину или ещё что-то — я готов на это, потому что знаю, что выигрыш от этого будет больше, чем то, что я теряю на каких-то микросекундах.
Анатолий: Да, прекрасно, что у тебя появляется выбор и ты этим выбором можешь воспользоваться, тебя никто не заставляет обязательно ходить на ходулях, зато ты гипотетически можешь реализовать какие-то возможности.
Сергей: Если ты хочешь выбор, у тебя есть Boost.
Дмитрий: Нуу, как сказать. Boost используется, хорошо, что он есть, но… Мы всё-таки в первую очередь смотрим на инструментарий из коробочки. Даётся мне тип std::string, я смотрю, что в нём есть. Там есть и size(), и length(), и у меня уже когнитивный диссонанс: зачем два, почему нельзя было что-то одно задепрекейтить? И тут появляется кто-то и говорит, что у нас легаси, мы уже не можем назад. Это немножко грустно, конечно. И это, мне кажется, вопрос, где мы никогда не найдём золотой середины. Потому что если отталкиваться от того, что нельзя ломать язык, то в нём остаётся много довольно безумных вещей, которыми обязательно кто-то будет пользоваться.
![](https://habrastorage.org/webt/nh/k7/cd/nhk7cdikdhqxbdfj52qibe_pybo.jpeg)
Компиляция
Дмитрий: Давайте немножко отойдём от этой темы и поговорим про другие насущные проблемы, например, такую, как банальная скорость компиляции. Что вы можете сказать по этому поводу?
Анатолий: У меня осталось впечатление от плюсов, что, когда я нажимал на кнопочку «компилироваться», сразу шёл заваривать чай.
Сергей: Всякое бывает.
Анатолий: И даже на embedded-устройствах, там тоже можно закрутить кучу include, миллион макросов?
Сергей: Ну это от архитектуры компиляции не зависит. Мы на embedded обычно кросс-компилируем.
Ну, и мы же все понимаем, из-за чего это? Мы делаем бинарник, у которого ничего нет, к которому не нужно ставить. Сколько сейчас инсталляция дотнета занимает?
Дмитрий: Сокращается постепенно. Раньше было 150 мегабайт. Сейчас можно как-то нарезать всё это на кусочки, это долгая дискуссия. Становится лучше.
Сергей: Я могу и про плюсы сказать, что всё становится лучше!
Дмитрий: Сейчас компьютерная игра, которую ты покупаешь в Steam, весит, например, 64 гигабайта. Скажи, тут 150 мегабайт погоду сделают?
Сергей: Ну, наверное, нет.
Анатолий: И компиляция у тебя происходит каждую минуту, а деплоишь ты свой продукт раз в неделю-две. Зачем оптимизировать время деплоя на уровне компиляции каждую минуту? Я хочу компилировать очень быстро, а потом, когда буду собирать под конкретную платформу, тогда да — пусть оптимизирует, вставляет свои оптимальные zero cost abstractions и прочее. Но зачем мне это платить каждую секунду-то?
Сергей: Я не очень понял про каждую секунду, мне кажется, как раз в дотнете платишь каждую секунду, как используешь приложение, нет?
Анатолий: Я имею в виду, что компиляция должна быть быстрой. Она не должна быть максимально оптимизирована, она должна быть быстрой, чтобы было комфортно разрабатывать.
Сергей: Ну, мы опять просто приходим к тому, что я могу сказать, что это легаси. У плюсов медленная компиляция — да, я с этим не спорю. Сейчас есть более прагматичные подходы, а плюсовый морально устарел. Но сделать с этим сейчас, не ломая ничего, очень сложно. Ну вот будут теперь модули, я надеюсь. Много проблем с легаси-кодом. А это всё растёт из C.
Дмитрий: Это очередная проблема. Есть у нас подход типа «модули». И я бы со своей колокольни сказал: ребята, мы переходим на модули и макросы больше не будут поддерживаться вообще никак. Более того, давайте со следующей версии, если включаешь модули, то отключаются макросы глобально везде. Вот это был бы мой подход. К сожалению, никто о таких кардинальных шагах не думает.
Сергей: Почему, о них думают. Но их не поддерживает комитет. Наверное, есть причины. Но я тебе предлагают сделать proposal. Это же открытое всё.
Дмитрий: Мы же понимаем, что это обречённый proposal. И обречён он по той причине, что никто не хочет внезапно сказать «надо переписывать»: допустим, в STL используются макросы, надо от них избавиться. Нужно, чтобы кто-то сделал волевое решение, сел и избавился от всех макросов.
Сергей: STL как раз не проблема по причине маленького размера. STL переписывают часто. Не знаю, хорошо это или плохо, но недавно STL переделали — много изменений, которые не заметны снаружи, но внутренняя логика у них поменялась.
Дмитрий: Ну видишь, а остальное — почему нельзя сказать, что остальное в топку? Если хотите модули, то у вас только greenfield. Мы не делаем brownfield development, только новые проекты. Новые проекты — значит, только модули. Старые проекты — без модулей. Нельзя так сделать?
Сергей: Комитет считает, что нельзя. Есть такие разговоры, но по сути, так работают экспериментальные версии. Не так радикально, что насовсем отключение. С модулями проблема именно с макросами, как правильно говоришь, и каждый топит за своё. G++ за своё, Clang за своё. Цена представительной демократии.
Дмитрий: Но тут, видишь, никто просто не допускает возможности того, что решение может быть радикальным. Сказать «последующие версии будут устроены так, что либо A, либо B». Для меня как для человека, который часть времени проводит в .NET, идея втаскивания макросов в модули безумна по своей сути. По аналогии, вместо того, чтобы втаскивать их в модули, вместо этого почему бы не сделать отдельные текстовые файлики, засунуть все экспортируемые макросы туда и сказать, что на этом как бы и всё?
Сергей: Потому что, по сути, ты предлагаешь делать новый язык. Согласись, это уже будет C++ 2.0. Или ++C++. Он будет относиться к плюсам так, как они относятся к C.
Дмитрий: Ну нет, я тут не соглашусь. Потому что мы тут в конечном счёте не обсуждаем язык, мы обсуждаем компиляторы, технологию компиляции. То, что там, может, и применяются инструкции, вместо #include будет #import или что-то в этом духе — это всё второстепенно. Мы обсуждаем, что у компилятора внезапно появится своё мнение насчёт вот этой проблемы. И, судя по всему, никто не хочет сказать, что давайте будет компилятор с особым мнением насчёт макросов в модулях, допустим.
Наше время подошло к концу. Если читателям окажется интересно, можно будет потом устроить ещё одну дискуссию. А пока предлагаю вам, коллеги, сказать небольшое завершающее слово на тему того, как вы видите ситуацию в C# и C++, что вы видите в будущем и какое у вас впечатление от сегодняшней дискуссии.
Анатолий: У меня укрепилось впечатление, что в плюсах сейчас занимаются вещами, которые должны были появиться 10 лет назад. Это всё происходит очень медленно, очень тяжело, и не факт, что будет в том виде, в котором должно быть, потому что обычно реализуется всё очень многословно, неудобно для программиста. И всё это можно свести к легаси и «исторически сложилось», но конечному программисту на это наплевать. Он хочет получать удовольствие от работы, и на плюсах сейчас получать удовольствие очень сложно.
C# разрабатывался, чтобы легко было переходить с C++. Если знаете плюсы, то вам переходить на C# не составляет никаких проблем совершенно. Но вы забываете практически о всех проблемах, самое плохое выбрасываете, оставляете самое хорошее. И у вас появляется новый язык, новая платформа, динамически развивающийся понятный программный комитет, компиляторы, новые JIT'ы — всё то, чем можно гордиться, радоваться каждый день новостям и не заботиться о каких-то грубых мелочах (какой у вас размер int). Мне кажется, выбор должен быть довольно очевиден, особенно для студентов, которые только задумываются о том, какой бы язык выучить.
Сергей: Ну, по тому, что я услышал, программистам на C# нечем гордиться непосредственно в своей работе — приходится гордиться работой программного комитета. Мне кажется, это как раз объясняет, почему на C++ приятно писать. Это сложно, и ты всегда видишь результат. Плюсы (по тому, что я знаю) — это обычно cutting edge. Как мы правильно говорили, не будет человек делать UI-приложение на C++, сейчас это просто не та ниша, где они нужны. А на C# — пожалуйста. На C++ ты пишешь код, который быстро работает.
И мы тоже следим за нашим комитетом, который развивает его. Сожалею, что я не смог донести, насколько сейчас всё хорошо и быстро развивается, и насколько современный C++ отличается от того, что вы, судя по всему, видели. Понятно, что есть и проблемы тоже.
Ну и у меня так и не получилось понять, насколько C# кроссплатформенный и независимый от Microsoft. Несмотря на то, что говорили о .NET Foundation, всё время все разговоры про то, кто что делает, были про Microsoft. Не совсем понятно, насколько хочется складывать все яйца в одну корзину и зависеть от одной компании.
Пост создан при поддержке конференций C++ Russia и DotNext. Напоследок опрос: а что поддерживаете вы?
Комментарии (360)
Alexey2005
30.09.2019 16:19+3Когда говорят о кроссплатформенности, то нет смысла рассматривать сферический язык в вакууме, потому что в современном мире мало кому нужен язык сам по себе, без фреймворков, библиотек и среды разработки.
Попробуйте-ка закодить, собрать и запустить бинарник с WPF-окошком, не выходя из Linux.
А то так и Objective-C можно считать кроссплатформенным, только за пределами Apple-платформ он неюзабелен.ForNeVeR
30.09.2019 16:51+14Вы выбрали изначально не кроссплатформенный пример. Точно так же и на плюсах нельзя закодить какое-нибудь MFC-окошко, не выходя из Linux (что, имхо, не говорит в пользу MFC, но вряд ли годится в качестве аргумента против плюсов).
А давайте теперь рассмотрим кроссплатформенный пример. На плюсах мы возьмём портабельную технологию Qt, а на C# — портабельную технологию Avalonia. И… ну, у нас выйдет закодить бинарник с окошком, не выходя из Linux. С некоторыми приседаниями мы его тут же заодно скомпилируем под Windows и macOS.
Что дальше? Какие выводы можно сделать, и нужно ли их делать?
Larymar
30.09.2019 17:03-2xamarin
avalonia ui
сейчас почти любой язык предложит целую кучу технологий
которые предложат кроссплатформенность во всех возможных сферахAlexey2005
30.09.2019 17:19+11Почему же тогда даже сама MS предпочитает писать кроссплатформенные приложения (Skype, Visual Code) на Electron? Наверное, с кроссплатформенностью .NET не всё так здорово?
Fedorkov
30.09.2019 18:21+1С кроссплатформенностью GUI там всё совсем плохо. То есть формально окошки и кнопки можно сделать одной библиотекой, но товарного вида под всеми тремя системами (Win, Linux, Mac) добиться очень тяжело.
Taraflex
30.09.2019 20:26+3Насчет VSCode Eleсtron был обоснованным выбором, ибо прежде всего оно затачивалось под web разработку на js/ts. Eleсtron позволил быстро нарастить базу плагинов, так как стало просто интегрировать существующие инструменты из npm.
В том же sublime есть множество плагинов, которые являются лишь python оберткой над v8 для использования возможностей js библиотек.
Да и в целом VSCode работает достаточно шустро, пока не открывать в нем файлы с очень длинными строками.
Ну а Skype… Просто представим, что оно закрылось и больше не существует.rusbaron
01.10.2019 14:50+1Да и в целом VSCode работает достаточно шустро, пока не открывать в нем файлы с очень длинными строками.
По моёму поверхностному взгляду, даже быстрее чем Sublime
impwx
01.10.2019 11:11+4Потому что сначала они разрабатывали вебовский редактор кода Monaco Editor для VS Online, а потом оказалось, что его можно упаковать в виде десктопного приложения...
MooNDeaR
30.09.2019 16:21+29Весь спор похож на спор про автомобили с автоматической и механической коробками передач :) Нет ничего плохого в том, чтобы выбрать для комфортной городской езды в плотном потоке автомобиль с автоматической коробкой передач. Да больше расход топлива (читай ресурсов компьютера), да некоторая потеря контроля за поведением автомобиля (читай сборщик мусора), но в свою задачу решает и позволяет совершать более безопасные манёвры. Но если уж ты участвуешь в гонке, в которой трасса известна (читай знаешь какое железо), и фиксированное количество автомобилей (известные условия задачи), то уж придется сесть за механику, чтобы выжать из автомобиля максимум :)
При этом никто не мешает, ессно, и по городу ехать на механике и на гонке использовать затюненный автомат :)
phillennium Автор
30.09.2019 17:40+9Я в целом согласен с вашим комментарием, но думаю вот что.
Помимо описанных вами различий, есть ещё много нюансов вроде «сколько стоит ремонт разных коробок передач». И люди могут заранее о таких нюансах вообще не задумываться, а потом говорить «чёрт, для меня это приоритетно, знал бы — сделал бы другой выбор».
Поэтому на такие нюансы полезно проливать свет. А подобные споры как раз их и проливают: «вот сломается твоя автоматика — разоришься». Разумеется, из этого не следует «механика всегда лучше», но это ценная информация. И читать такие споры, по-моему, стоит не как «что лучше», а как полезную информацию о различиях.
0xd34df00d
01.10.2019 20:10-1Только в рамках этой аналогии давно придумали другие машины, которые едут не медленнее, но при этом безопасности и гарантий дают больше.
Да, тот же Rust, а до Rust — ATS какой-нибудь.
seslomayer
01.10.2019 20:19Только в рамках этой аналогии давно придумали другие машины, которые едут не медленнее, но при этом безопасности и гарантий дают больше.
Пример вам выше дан — вам осталось показать безопасность и «не медленнее». Хотя «не медленнее» вы уже показать не сможете, но хотя-бы безопасность покажите.
Inobelar
30.09.2019 16:23+13Анатолий: Мне кажется, что C# движется в сторону плюсов, он пытается отвоевать их рынок. А вот плюсы уже не движутся никуда.
Сергей: Откуда это? Что значит «плюсы не движутся никуда»?После такого выпада, конструктивный диалог закончился. Да и до этого момента выглядел как просто троллирование плюсов.
Nagg
30.09.2019 16:35+10Я еще ни разу не видел конструктивных бесед ЯзыкХ вс ЯзыкУ :)
IRainman
30.09.2019 16:41+1Были такие беседы на моей памяти. Но в целом я не понимаю зачем ибо выбор языка должен исходить из условий стоящей задачи и доступных возможностей.
Kanut
30.09.2019 18:53Да почему же. На мой взгляд это совсем не исключено и зависит скорее от того кто спорит.
Правда я бы сказал что и сравнивать наверное надо не любые "сферические языки в вакууме", а языки более-менее "эквивалентные" в контексте какой-то конкретной задачи. Тогда вполне себе конструктивные дискуссии часто получаются.
FForth
30.09.2019 16:40+1Полезно ещё и знание, а на каком языке X сделан сам язык Y
Часть вопросов, тогда, сами отвалятся. :)MayRiv
01.10.2019 13:57Это не значит вообще ничего. Да и в основном, языки написаны сами на себе. Условно компилятор Хаскеля написан на Хаскеле, и это спорно считается самой сложной программой, написанной на хаскеле:)
0xd34df00d
01.10.2019 20:12Неудивительно. Это на самом деле вообще один из самых сложных компиляторов, если не самый сложный.
0xd34df00d
01.10.2019 20:14Сергей на самом деле тоже имеет интересную позицию. То ему не нравится, когда есть компилтайм-надёжность («Я не хочу, чтобы моя программа что-то проверяла в compile time без моего ведома.»), то он считает, что модули существенно улучшат время компиляции (нет, не улучшат, время компиляции в современных плюсах идёт от шаблонов и constexpr-вычислений, а им модули не помогут никак).
IRainman
30.09.2019 17:02+1Дмитрий: Это очередная проблема. Есть у нас подход типа «модули». И я бы со своей колокольни сказал: ребята, мы переходим на модули и макросы больше не будут поддерживаться вообще никак. Более того, давайте со следующей версии, если включаешь модули, то отключаются макросы глобально везде. Вот это был бы мой подход. К сожалению, никто о таких кардинальных шагах не думает.
Сергей: Почему, о них думают. Но их не поддерживает комитет. Наверное, есть причины. Но я тебе предлагают сделать proposal. Это же открытое всё.
Дмитрий: Мы же понимаем, что это обречённый proposal. И обречён он по той причине, что никто не хочет внезапно сказать «надо переписывать»: допустим, в STL используются макросы, надо от них избавиться. Нужно, чтобы кто-то сделал волевое решение, сел и избавился от всех макросов.
Бгыгы. Объясняю почему не трогают макросы и почему proparsal обречён: Как мне подключитьмодульхидер в зависимости от платформы под которую это собирается? Как мне генерировать в коде имена переменных и функций? Где статическая рефлексия? Вот поэтому комитет и не трогает макросы потому что много кода просто невозможно переписать без них. Да есть всякие сторонние генераторы, но макросы поддерживаются любым компилятором из коробки, а с утилитами могут быть сложности, что делает концепцию ущербной как на уровне «поддержки из коробки» так и с вопросами кроссплатформы.
P.S. «Магию» в Boost тоже стоит посмотреть ибо это фактически кусок STL feature или extented — как угодно можно назвать, но без Boost тяжко, а подключается он просто.PyerK
01.10.2019 15:18Как мне генерировать в коде имена переменных и функций? Где статическая рефлексия?
Всё это есть тут:
cppx.godbolt.org
Можно собрать себе среду.
Я попробовал, мне понравилось.
mezastel
02.10.2019 09:38Бгыгы. Объясняю почему не трогают макросы и почему proparsal обречён: Как мне подключить модуль хидер в зависимости от платформы под которую это собирается?
Точно так же, как это делается в тех языках, где модулей нет. И если вам где-то не хватает метаданных, напомню что это одна из проблем, которые модули могут теоретически решить. Conditional compilation на базе модулей — это плохо, помимо всего прочего это превращает код в нечитаемую кашу из -ов. То что люди привыкли так работать не значит что это хорошо.#ifdef
Как мне генерировать в коде имена переменных и функций?
Вы сейчас снова жалуетесь на тот функционал который, помимо того что он нишевый, не решается только путем макросов. В C#, например, можно автоматически присвоить переменной значение, равное названию вызываемого метода. Это делается на уровне кода, а не на уровне макросов. То что метаданные еще не подвезли это просто еще одна проблема, которую нужно решать вместо того чтобы натягивать сову на глобус.
“Магию” в Boost тоже стоит посмотреть ибо это фактически кусок STL feature или extented — как угодно можно назвать, но без Boost тяжко, а подключается он просто.
Любая “магия” (например, использование Boost PP) плохо читается и понимается, что приводит к вполне очевидным maintenance costs.IRainman
02.10.2019 15:12Вы сейчас снова жалуетесь на тот функционал который, помимо того что он нишевый, не решается только путем макросов.
То что метаданные еще не подвезли это просто еще одна проблема, которую нужно решать вместо того чтобы натягивать сову на глобус.
Ну да, всё так, а с учётом факта что в плюсы сейчас вливают успешно появившееся лет 10 назад, а кое что появилось и раньше, либо в других языках либо в куче внутренних pragma от компиляторов, то трогать макросыещё долгов ближайшей перспективе никто не будет примерно с тем же определением это «мало кому и редко кому нужно, нишевая задача, уже работает везде одинаково, и т. д. и т. п.». Не знаю в чём уж совсем «ужас» макросов, с тем же успехом можно сказать что в регулярных выражениях тоже ведь «ужас». Макросы позволяют очень гибкую кодгенерацию из коробки, хоть и трудно поддерживаемую, но которую без полноценной рефлексии не сделать вообще никак.
Кстати говоря constexpr выражения уже кое где позволили заменить макросы нормальным кодом, это уже очень хорошо и это правильное движение.
xtovo
30.09.2019 18:01+5> в плюсах сейчас занимаются вещами, которые должны были появиться 10 лет назад.
Я бы сказал 20 лет назад. Когда-то работал в ЦЕРНе, в команде ROOT (https://root.cern.ch/).
Уже тогда у нас был C++ интерпретатор, Reflection, всевозможные контейнеры, тесный контакт с Страустрапом. Уже тогда обсуждалось, как добавить все эти фичи в стандарт C++.
Но, воз и ныне там.
Сейчас для «низкоуровневого» программирования (видео, DirectShow, MF, COM, железки) пользую C++. Для всего остального — C#.
Мои любимые продукты DeExpress, Resharper.
seslomayer
30.09.2019 19:23+1Уже тогда у нас был C++ интерпретатор
То, что С++ нужно сейчас и просто «интерпретатор» — это разные вещи.
Reflection
Уровня «обойти поля пода»? Это тоже не то, что требуется от С++.
Уже тогда обсуждалось, как добавить все эти фичи в стандарт C++.
Да, но тогда это было позором. Эта была попытка напихать чего-то невнятного лишь бы напихать, но о чудо — комитет одумался.
Для С++ не подходят решения других языков, но не это главное — подобных решений нигде не было и нет. Где есть компилтайм-рефлексия? Да нигде, а где есть — там на уровне языка существуют одни поды(либо чуть-чуть больше). Откуда всё это брать?
За примерами далеко ходить ненужно. Достаточно посмотреть чем были концепты тогда, чем они являются сейчас. Я бы не хотел иметь то, что было раньше.
И можно только порадоваться за С++, что комитет выбрать путь решения глобальных проблем, а не затыкания как попало локальных дыр. И лучше пусть не будет ничего, чем появится что-то убогое, что закроет путь чему-то адекватному.
Тоже самое касается и рефлексии. Достаточно посмотреть на то, чем она была тогда(но уже тогда она была по-сути уникальной в своём роде. Даже в каком-нибудь D пошли по пути наименьшего сопротивления — сделали eval) и чем является сейчас. Лично мне и сейчас не нравится и противник ODR и всего, что с ним связано. В этом плане тот же шарп мне ближе.xtovo
30.09.2019 19:44+5Я не хочу троллить.
Свою миллионную линию кода на 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# с операционной системой.
Kanut
30.09.2019 19:51+2С++ тоже на месте не стоит. Но да, я наверное соглашусь что особенно в последнее время Microsoft стал очень активно развивать С#. Как впрочем и другие свои языки/фреймворки и всю сопутствующую "инфраструктуру"/тулинг.
xtovo
30.09.2019 20:14+2> Microsoft стал очень активно развивать С#
Когда-то я достаточно едко высказывался о Мише де Икаса, когда он начинал свой Mono, с GUI на основе Gtk++. Как я был не прав!
Но, именно Mono позволило портировать C# на Linux, iOS, Android.
Antervis
30.09.2019 21:18-6Но да, я наверное соглашусь что особенно в последнее время Microsoft стал очень активно развивать С#
microsoft и с++ начали активно развивать, но, чисто статистически, лучше бы они этого не делали
seslomayer
30.09.2019 20:52-3Свою миллионную линию кода на 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# с операционной системой.
И что это должно значить? Лично меня не интересует ни эта «операционная система», ни какая-то интеграция в ней. Моё отношение к сему — есть ваше отношение к С++(вернее к тому, что вы неправильным образом называете С++).xtovo
01.10.2019 09:20+3мой последний комментарий втему
> Интерпретатор достаточно примитивная вещь, которая мало кому нужна.
Это не примитивная вещь.
Когда четверть века назад Masaharu Goto (мой друг Маса) решил написать C++ интерпретратор (CINT), все в один голос уверяли, что это невозможно сделать.
А, он сделал. Конечно, за это время была проделана большая теоретическая работа по алгоритмам написания интерпретатора и сейчас это сделать гораздо проще.
Если бы 20 лет назад приняли C++ интерпретратор,
то все эти питоны, баши, пых-пыхи, пёрлы оказались в мусорной корзине истории.
Все заменил бы C++
Это именно тот путь (единый язык для любой задачи, везде C#) по которому пошли мелко-мягкие, и несомненно, это позволило им сделать прорыв в технологии программирования.
Не видеть этого может только человек страдающий когниктивным диссонансом.
> Рефлексии нигде нет и никто не знает как она должна выглядеть для вводных С++
Именно благодаря «рефлексии» был пойман Бизон Хиггинса, заполнена самая большая база данных в мире. Я имею ввиду данные с Большого Адронного Коллайдера. Это, так называемый, ROOT data format, который на 101% основан на «рефлексии».
++
Хочу добавить последние 2 копейки…
Когда один из «экспертов» говорит
«Я тут хотел уточнить. Я про C# мало знаю, сам трогал его очень давно, в самых первых версиях»
дискуссию на этом можно было бы и закончить!
xtovo
04.10.2019 10:33Решил таки продолжить…
Сегодня прослушал отличный доклад, про отличную либу, которая реализует рефлексию на C++ (14).
channel9.msdn.com/Events/CPP/CppCon-2016/CppCon-2016-C14-Reflections-Without-Macros-Markup-nor-External-Tooling
github.com/apolukhin/magic_get
Она уже часть boost.
Ждем, когда станет частью языка.
easyman
30.09.2019 18:08-6У меня сломался Console.Beep() в C# + Windows + RDP.
Поплюсуйте, пожалуйста, на GitHub!
github.com/dotnet/corefx/issues/41437easyman
30.09.2019 18:50-2Кстати, в C++ он тоже должен быть сломан. Я не проверял.
easyman
30.09.2019 19:42-1Проверил. Сломан и там.
github.com/dotnet/corefx/issues/41437#issuecomment-536646193
Taritsyn
30.09.2019 18:33+2По поводу КДПВ: лучше бы взяли Саб-Зиро и Рейна из Ultimate Mortal Kombat 3, и тогда не пришлось бы перекрашивать Скорпиона.
phillennium Автор
30.09.2019 18:52+5Да, мы сами это в рабочей переписке сегодня обсуждали, но к тому моменту пост уже был готов :)
Kanut
30.09.2019 19:06+4Для меня немного странная постановка вопроса и немного странная дискуссия. Сам в своё время начинал на С/С++, а потом всё больше и больше ушёл в С#. И для меня это просто немного разные "инструменты".
И сравнивать их это как сравнивать ну скажем топор и молоток. Вроде в чём-то похожие и местами один может худо-бедно заменить другой, но на мой взгляд не особо логично пытаться выяснить кто из них "лучше".mezastel
02.10.2019 09:41-3Молотком можно только отбить палец. А топором обрубить себе процесс в продакшне.
seslomayer
30.09.2019 19:10+12Анатолий: Мне, кстати, недавно попалась отличная статейка, где автор на разных языках (около 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), далее уже этот шарп/раст/го вызывает сишную логику, которая копирует данные и обеспечивает всё остальное.
Соответственно, всё сразу становится на свои места. Чем больший кусок данных мы пробрасываем через шарп/раст/го — тем меньше раз мы обращаемся к ним и тем меньше мы теряем на оверхеде. Т.е. по-сути чем правее — тем меньше шарпа/раста/го. А значит, что отсылка на правую часть графика — это призыв отказаться от шарпа/го/возможно и раста.
zhaparoff
01.10.2019 00:17-1Возможно, в некоторых моментах вы и правы, но мне кажется критика теста не вполне обоснована.
Драйвер в первую очередь это софт, реализующий какой-либо стандартизированный интерфейс, для того чтобы ОС могла как-то унифицированно общаться с огромным зоопарком железячных устройств. Обычный фасад, у которого понятное определенной ОСи лицо, и вызовы железного 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 мегапопугаев в секунду» в итоге ничего не говорят о языке и/или его применимости в задачах другого типа. Но в целом, да, тест приведен, возможно, не совсем к месту. Но от этого он сам не становится некорректным.seslomayer
01.10.2019 01:27+2Собственно, очень многие драйверы, включая драйверы дисков, звуковых, сетевых и видео карт, занимаются в основном именно тем, что вы описали, — конфигурируют 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 он плох. Он плох во всём.
Исходя из того насколько сильно его форсят, насколько удобные там результаты, насколько несостоятелен он сам по себе — я могу с достаточной долей уверенности предположить — возможно это целенаправленный вброс, либо попросту глупость. Но пусть будет глупость.
dim2r
01.10.2019 09:51Я согласен, что данный тест скорее показывает что на С#/Rust/Go/etc. можно писать драйвера с приемлемой производительностью.
Насколько понимаю, драйвер должен работать в режиме kernel mode, а эти языки обеспечивают только user mode. То есть есть накладные расходы на переключение между режимами при каждом чихе. Чистый kernel mode возможен только на С и ассемблере. Даже С++ не может работать в этом режиме понормальному.Gorthauer87
01.10.2019 10:30+3Rust и плюсы могут работать в чистом kernel mode, нужно лишь отключить фичи рантаймов.
Ну и учитывая специфику, не увлекаться шаблонами.dim2r
01.10.2019 11:03В каком-то ограниченном диапазоне могут. Еще вопрос — на какой платформе — Window или unix?
Gorthauer87
01.10.2019 11:05+1Вот прямо сейчас на redox-os. В остальных случаях особо тоже не вижу проблем фундаментальных.
А вообще, интересная идея в том, чтобы вообще не использовать кольца защиты и полагаться на изоляцию wasm рантайма.
В интернете где то лежит прототип такой оси.
math_coder
01.10.2019 18:11Ну и учитывая специфику, не увлекаться шаблонами.
Это в смысле для снижения размера бинарника?
IRainman
02.10.2019 15:23-1Не использовать кучу, например ;) А это значит, что, к примеру, std::string в драйвере уже нельзя использовать, но зато std::string_view можно.
sborisov
30.09.2019 22:11+1По мне все эти споры больше дело вкуса. Мне допустим Java кажется намного логичнее C# из-за меньшего количества сущностей, и ничего не могу поделать.
Последние изменения стандарта C++, как мне кажется — попытки исправить проблемы которые привнесло метапрограммирование.
А ещё я на днях посмотрел пост про развитие стандарта C, прямо все больше и больше люблю С, очень стройный и логичный язык.
Вот ссылка, кому интересно.seslomayer
01.10.2019 02:49-2Последние изменения стандарта C++, как мне кажется — попытки исправить проблемы которые привнесло метапрограммирование.
Странное заявление. Как можно исправить проблемы метапрограммирования добавив его ещё больше? Клин клином? Проблемой С++ было(и есть) малое кол-во метапрограммирования и малое ко-во фич. А так же, проблемой С++ является его изначальный дизайн со множеством скрытой семантики и откровенных дыр, но такой дизайн присущ всем ЯП.
А ещё я на днях посмотрел пост про развитие стандарта C, прямо все больше и больше люблю С, очень стройный и логичный язык.
Видео запоздало лет на 20. Всё это(и больше) всегда было в gnuc(который стандарт де-факто в мире си), откуда и перебралось в стандарт, причём почти всё перебралось ещё те самое 10-20 лет назад.
DistortNeo
01.10.2019 16:50+2Как можно исправить проблемы метапрограммирования, добавив его ещё больше?
Сделав код проще и понятнее, пусть и за счёт усложнения самого языка.
seslomayer
01.10.2019 17:23Сделав код проще и понятнее, пусть и за счёт усложнения самого языка.
Ну дак там говорится не о сложности мета-программирования(хотя тезис уже спорный — где есть ещё более простое мета-программирование? В D? Мне лично не особо оно нравится и выглядит, опять же для меня, ужасно), а о самом мета-программировании.
К тому же именно мета-программирование сделало из C++ то, чем он является и решило множество проблем везде и всюду. Тезис абсолютно некорректен. А то, что его можно упростить и улучшить — да, конечно. Но тезис всё равно некорректный.
DistortNeo
02.10.2019 16:03хотя тезис уже спорный — где есть ещё более простое мета-программирование?
Ну да, ассемблер простой. Но программы писать на нём почему-то сложно. Поэтому люди придумали высокоуровневые языки.
Кстати, именно в C++ мета-программирование называть простым у меня язык не поворачивается. Концептуально всё просто, но из-за большого количества подводных камней получается уже сложно.
dim2r
01.10.2019 09:56+2Мне допустим Java кажется намного логичнее C# из-за меньшего количества сущностей, и ничего не могу поделать.
В java до сих пор нет checked arithmetics.
int foo = Integer.MAX_VALUE + 1; // тут должно быть исключение, а его нет. источник трудноуловимых отсроченных ошибок
DistortNeo
01.10.2019 16:46+3Мне допустим Java кажется намного логичнее C# из-за меньшего количества сущностей, и ничего не могу поделать.
А мне Java не нравится из-за ограниченных языковых возможностей по сравнению с C#. Даже структур нет и полноценных дженериков.
Аналогично кому-то будет нравиться Go за простоту, а кому-то C++ — за возможности.
DeuterideLitium6
30.09.2019 22:31А по мне самый лучший ЯП, это тот который ты лучше освоил.
math_coder
01.10.2019 18:59+2Я освоил Basic разлива УК-НЦ по максимуму, и я гарантирую, что это не лучший язык даже среди тру-бейсиков.
Fulcrum013
03.10.2019 18:23Та ладно таких веселых васиков больше нигде нет. Если в видеопамять по отрицательному адресу писать оно рисует отам вверху экрана, где типа верхней строки состояния. И убрать то что нарисовал никакими комадами clear и т.д. не уберешь. только ребут ну или опять же программно затереть. Информатичку чуть инфаркт не хватил когда она там логотип IBM увидела и убрать не шмогла.
FForth
01.10.2019 19:57Ага, Форт, тут и метапрограммирование и разделение синтаксиса и семантики и низко-высокоровневые слои применения языка, но увы слишком много отличий от майнстрима и корпоративного использования. :)
keydon2
01.10.2019 00:08-1Хотел бы я посмотреть как придёт самсунг и скажет мелкософту что этой фичи в новом дотнете не будет. Практически весь c# контролируется мелкософтом, любой форк, предлагающий координальные изменения будет раздавлен в течение пары дотнетовских версий. Опять же под линь и мак никто не пишет на c#, несмотря на xamarin. Все понимают что это язык одной компании под одну операционку, но продолжают утверждать, что он кроссплатформенный и его развитие распределено.
sand14
01.10.2019 02:03+1Под одну операционку это ныне замороженный (is done) .NET 4.8.
А актуальный .NET ныне — это Core 2.2/3.0 для бек-енд разработки, которую ведут обычно под Windows, но таргетируют как для Windows, так и для Linux.
И сейчас Core прямо выстрелил — после многих и многих лет застоя стартовало много бек-енд проектов на рынке.
Ну а с кроссплатформенной разработкой, похоже, в итоге не сложилось. И надо ли? Есть много других современных средств.
kvghabr
01.10.2019 10:31Можно писать на vscode под линуксами, но debuger придется от самсунга прикручивать, либо пользоваться проприетарным от микрософт в комплекте с vscode.
petuhov_k
01.10.2019 16:50+1Rider под linux работает не намного хуже, чем под wndows. А в чем-то даже лучше.
Barbaresk
01.10.2019 22:08+2Юзаю Core 2.3. Так вот, один из самых важных фреймворков — Entity Framework до сих пор до ума не допилен. Год назад, когда я на него перешёл, там не было GROUP BY (!), за год вот появилось, также как и конструкция IN. Но до сих пор нет UNION, какие-то проблемы были с DISTINCT (сейчас не вспомню что именно, но были). Про enity-sql и говорить не приходиться. Хотя непосредственно ASP .NET Core мне зашёл больше чем виндовс-онли ASP .NET MVC, благодаря многим улучшениям.
Dansoid
02.10.2019 01:26Уже лучше. EF Core 3.0 имеет еще более допиленный Change Tracker, Code First, и чуток лучший парсер Expression Tree, но это не значит лучший SQL. Использовать ли это в продакшине, хотя нет, использовать ли это для высоких нагрузок — решать вам.
Barbaresk
02.10.2019 01:30В 3.0. так и не завезли пока union. Я-то кое-как выкртился, а вот в теме на гитхабе по union много тех, кто печалится от этого.
Dansoid
02.10.2019 02:53Как это не завезли??? Видать «конкуренты» до сих пор абстрактной «фигней» над абстрактным хранилищем страдают.
Для жаждущих пока только для 2.1, на след неделе докручу к 3.0, а то немножко там нарефакторили и надо легкий тюнинг — linq2db.EntityFrameworkCore
Редко меня можно удивить SQL запросом который я не могу на LINQ написать.
euroUK
02.10.2019 08:53+1Мое мнение, что когда в запросах доходит дело до GROUP BY и прочие UNION, то в большинстве случаев я хочу дернуть хранимку чтобы быть уверенным, что оно работает как я хотел.
Лично я 2 года в продакшене использую EF Core и не было того, чтобы я сделать не смог. Не всегда элегантно, но работало. Плюс перформанс, если использовать AsNoTracking весьма хорош, по сравнению с обычным или упаси Боже, нхибернейтом.Barbaresk
02.10.2019 14:33Ну я всегда после написания чего-либо на LINQ проверяю через профилировщик (или как он там). Вспомнил, кстати, в чём проблема с DISTINCT. Конструкция типа: COUNT (DISTINC ...)… GROUP BY пока не преобразуется в SQL.
Dansoid
03.10.2019 14:37Может еще и оконные функции вспомним? И, думаю, никогда или не очень скоро будет поддерживаться. Разрабатывают EF Core очень квалифицированные специалисты, но к реальной разработке высоконагруженных систем, имеющие далекое отношение. По этому не удивляйтесь поставленным приоритетам.
euroUK
03.10.2019 14:45Причем тут высокая нагрузка (особенно с Union, ага). Ни разу не видел, чтобы ОРМ использовали для высокой нагрузки. Для этого просто дергаем хранимку/вьюху из базы, где ее пишет DBD, а не EF с горы. Да, это гораздо медленнее в разработке, но когда я думаю про хайлоад, я подразумеваю, что деньги на ДБД и время на нормальную разработку есть.
Barbaresk
03.10.2019 17:22Меня в целом устраивает Ef core, так или иначе получалось обойти все ограничения и добиться нужного без использования хранимок. Asnotraking, кстати, в моем случае прибавил не производительности, а снизил потребление оперативки (ну и оптимизация некоторых linq конструкций тоже резко снизила потребление оперативки).
Просто переход с классического EF на EF Core полтора года назад был достаточно неприятным (в классике активно использовался Entity SQL) и самым сложным моментом из всего перехода с ASP.NET MVC на ASP.NET MVC Core. А использовать классический EF на Core было как-то не красиво.euroUK
03.10.2019 17:57AsNotraking снижает потребление памяти в классических REST сценариях, когда по-сути, контекст живет только время обработки реквеста. Мы просто не кэшируем в памяти всю эту хрень.
А в чем были именно сложности перехода? Есть конечно костыли до сих пор, но особых сложностей я не видел.Barbaresk
03.10.2019 18:54Основная проблема была в том, что 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 мб). Причину пока не установил, но где-то я явно напортачил.
mayorovp
03.10.2019 19:06Пропал Model First подход. Это, конечно же, был наиболее неудобный из всех подходов, но переписать легаси всё равно не так просто.
Пропали инструменты для автоматизации Database First — подхода.
То, что раньше делалось через edmx, теперь надо делать через DbModelBuilder. Стало намного проще, но все старые костыли снова в мусорку.
Entity SQL тоже пропал, запросы надо переписывать
Довольно неудобно, что сам EF Core вроде как для .NET Standard написан, но вот для миграций нужен .NET Core и никак иначе.
Dansoid
03.10.2019 21:12Потому EF не может. Хранимки это и есть костыли. Шаг влево, шаг вправо — FromSql или хранимки. Выигрыш использования LINQ слегка пропал. Если в инструменте сплошные ограничения, я чувствую себя как на минном поле. Но ниче, потом так и рождаются сертифицированные специалисты — они знали, они плавали.
QtRoS
01.10.2019 19:40Это Вы из какого года нам пишете?
Сообщество очень активно участвует в разработке с 2014 года, причем изменения далеко не минорные. Например, привнесение платформенных SIMD в 3.0 сделано не разработчиком MS, насколько я знаю. И форки при таком подходе не нужны абсолютно, более того — они вредны.
hddscan
01.10.2019 07:37У .NET есть куча ужасных косяков со скоростью в некоторых системных вещах.
Например получения и обработка всех файлов в директории.
На WinAPI эта часть может работать до 10 раз быстрее, чем на truъ .NET-е.
В итоге C++ CLI для таких задач лучше всего (боль маршалинья всех WinAPI на C# невыносима)Fulcrum013
01.10.2019 10:07-9При этом если учесть что шарп это вооще не C а ява++ то все становится на свои места. Это не какой не С++++ а Simula-67++++.
Ну а если к этому присовокупить что GC полностью устарел по состоянию на конец 60-х потому что для ООП не дает вообще никакой автоматизации и в купе с неумением статической композиции и размещения временных объектов на стеке, полностью исключают многопоточность, превращая ее в эмуляцию однопотока на многоядерном проце, дженерики не позволяют определять алгебру над сущностями, модули паскалевского разлива не позволяют иметь несколько реализаций к одному заголовку и несколько заголовков к одной библиотеке…
Ну в общем сразу становится ясно почему С++ наиболее высокоуровневый язык на сегодняшний день. А то что быстрый и годен для системного уровня — ну так получилось.CyberKastaneda
01.10.2019 11:08+5Вроде как шутки про GC уже давно deprecated
Fulcrum013
03.10.2019 01:11-2Ну да. Очень давно. На конец 60-х стало отчетливо ясно что он полностью непригоден для ООП. А в начале 80-х во всех профессиональных ООП языках от него отказались в пользу более совершенной, гибкой и эффективной кастомизируемой автоматики управления жизненным циклом.
Chaos_Optima
01.10.2019 12:37+2размещения временных объектов на стеке, полностью исключают многопоточность
Вообщето C# умеет размещать объекты на стеке правда только struct. И как это мешает многопоточности?Fulcrum013
03.10.2019 01:19-2В стандартной библиотеке классы которой и используются в основном как временные каков процент оных struct?
А любой new при создании их на эмулированном общем стеке (это то что ошибочно называют кучей в шарпе) требует синхронизации доступа к указателю оного стека. Т.е. все потоки выстраиваются в очередь на каждом шагу.
При размещении же объектов на аппаратном стеке, который для каждого потока свой, такая синхронизация не требует. При этом в реалиях плюсов свою субкучу для каждого потока иметь — ну это вопрос зависящий только от необходимости такой субкучи для конкретной задачи, и вся автоматика управления жизненным циклом для такой субкучи продолжает работать в штатном режиме.
В отличии от шарпа где и с организацией субкучи поплясать с бубном придется и GC в ней работать точно не будет.Chaos_Optima
03.10.2019 02:23+1Ну да ведь в параллельных потоках обязательно нужно выделять новые объекты, нельзя же работать с существующими или использовать локфри пулы, или сотню других алгоритмов.
А любой new при создании их на эмулированном общем стеке (это то что ошибочно называют кучей в шарпе) требует синхронизации доступа к указателю оного стека.
хм… Интересно где вы подобное прочитали? Вообще вопрос выделения памяти в С# довольно таки сложный (хотя по вашему он простой и тупой как 5 копеек), они используют столько уловок, что выделение памяти в C# работает быстрее нежели родной и горячо любимый malloc, и я почему то более чем уверен, что аллокация в C# локфри, особенно если учитывать как легко пишутся лофри аллокаторы (из собственного опыта написания локфри аллокаторов)
И да, чуть не забыл, структурные переменные в C# которые на стеке создаются без newFulcrum013
03.10.2019 07:22-2что выделение памяти в C# работает быстрее нежели родной и горячо любимый malloc
Единичный new в шарпе иногда быстрее. Но только исключительно за счет гигантского отложенного оверхеда. При этом если учесть тот факт что вызовать new в плюсах надо в сотни раз реже чем в шарпе то как бы шарп в этом плане отстает в десятки раз. Это при том что глобальный new в плюсах не предназначен для создания мелких единичных объектов хотя и может для этого использоваться. В основном он используется для создания субкуч выделение из которых идет по оптимальному для обслуживаемой структуры данных алгоритму.
Fulcrum013
03.10.2019 07:30-2работает быстрее нежели родной и горячо любимый malloc
в синтетическом тесте который использует менее 50мб предвыделенной памяти для там нескольких тысяч распределений когда плюсы отгрызают эту память у оси постранично и с игнорированием того факта что в плюсах вместо эти нескольких тысяч вызовов new достаточно одного который выполняется в тысячи раз быстрее даже с отгрызанием памяти?Chaos_Optima
03.10.2019 12:18Ды нет, если не писать свой аллокатор для плюсов, то шарповый аллокатор всегда быстрее, за исключением может только больших кусков памяти.
Fulcrum013
03.10.2019 07:37-1Ну да ведь в параллельных потоках обязательно нужно выделять новые объекты, нельзя же работать с существующими или использовать локфри пулы, или сотню других алгоритмов.
ну к примеру вектора складывать, матрицы перемножать и т.д. и т.п. И промежуточные результаты таких операций как не крути а временные объекты.
Fulcrum013
03.10.2019 07:47-2Вообще вопрос выделения памяти в С# довольно таки сложный (хотя по вашему он простой и тупой как 5 копеек)
Да нет там никаких уловок. Просто смещается указатель на конец эмулированного стека. Поэтому сам new и быстрый всегда O(1), а у плюсов глобальный new O(1) только на полностью нефрагментированной куче, на фрагментрированной O (Log (n)) от количества свободных дыр. Но зато имеет постоянный гигантский оверхед по содержанию живых объектов, пропорциональный O(n) от живых объектов, в отличии от плюсов которые тратятся только на рождение и похороны, причем преимущественно массовые. Это уже не говоря про отложенный оверхед на абсолютно бесполезную в системе со страничной организацией виртуальной памяти дефрагментацию, без которой GC жить не может, и этого «быстрого» new тоже не будет.Chaos_Optima
03.10.2019 12:22+1Ох лол, и вы говорите это просто. Дефрагментация памяти, бесполезная, да вот только благодаря ей C# сильно обгоняет С++ в выделении памяти, а ещё делает вычисления более кэшфрендли.
Fulcrum013
03.10.2019 18:11-2Дефрагментация памяти, бесполезная, да вот только благодаря ей C# сильно обгоняет С++ в выделении памяти
Зато очень сильно отстает в хранении.
а ещё делает вычисления более кэшфрендли.
Этой байке уже реально 70 лет. Только не кеш френдли а минимизирует перемотку перфоленты. У вас ОЗУ до сих пор на перфоленте? Алииния кеша она как не крути 64 байта. А за ними промах.Chaos_Optima
03.10.2019 18:33Вы не понимаете о чём говорите, попишите высокопроизводительные программы и поймёте насколько велико значение кеша.
0xd34df00d
03.10.2019 18:59Так в высокопроизводительных программах просто берут arena allocator и получают предсказуемую дружественность к кешу, а не рассчитывают на умный рантайм.
Chaos_Optima
03.10.2019 19:03Само собой, я просто говорю, что его утверждения про то что кеш не имеет особого значение не соответствуют реальности.
Fulcrum013
03.10.2019 19:33-1что его утверждения про то что кеш не имеет особого значение не соответствуют реальности
Где то сказано что он не имеет значения? Сказано что дефрагментация тут не при чем вообще.
Fulcrum013
03.10.2019 07:53-1что аллокация в C# локфри, особенно если учитывать как легко пишутся лофри аллокаторы (из собственного опыта написания локфри аллокаторов)
Локфри она может быть только из разных субкуч/пулов а соответсвенно должен быть механизм явного назначения субкучи/пула потоку.
И как понимаю GC с объектами выделенными из этих пулов тоже не дружит?Chaos_Optima
03.10.2019 12:28зачем явно то назначать? И без явного всё работать будет, в любой функции в любом месте можно получить id потока в котором она работает.
Fulcrum013
03.10.2019 09:43-2пишутся лофри аллокаторы (из собственного опыта написания локфри аллокаторов)
т.е. и 20 лет помучались и поняли таки что памятью надо управлять вручную, хотя это было доказано еще 50 лет назад?
Ну в общем если шарп до ума довести то однозначно плюсы получатся.
Интересно сколько времени у шарперов займет понять что кроме ручного управления памятью еще и автоматика управления жизненным циклом нужна, которая в плюсах уже лет сорок есть?Chaos_Optima
03.10.2019 12:27+1Не, это из С++ опыта, я просто плюсовик, С++ мой любимый язык, обожаю метапрограммирования и ненормальное программирование, C# на самом деле в работе не использую, но честно признаю (ибо сам тестил) что в C# выделение памяти работает намного быстрее стандартного малока.
автоматика управления жизненным циклом нужна, которая в плюсах уже лет сорок есть?
Вы про IDisposable чтоли который в C# очень очень давно появился?Fulcrum013
03.10.2019 18:29Я про автоматическое управление жизненным циклом. Про автоматическую деинициализацию объекта при выходе его из скопа/деинициализации содержащего его объекта. Именно это позволяет кастомизируемо решать задачу автоматического управления как ресурсами/объектами так и взаимосвязями объектов. Память при этом рассматривается как вид ресурса.
GC этого не умеет от слова совсем. Да и задачу управления буферами памяти GC решает только в случае если задача управления взаимосвязями полностью решена. иначе течет косвенными утечками. Ручное же решение задачи управления взаимосвязями ничем не отличается от ручных вызовов delete и при этом делает GC абсолютно ненужным.Chaos_Optima
03.10.2019 18:35Структуры удаляются, у IDisposable вызывается dispose при выходе из using. Где нужно управлять ресурсами этого хватает за глаза.
Fulcrum013
03.10.2019 21:55-1Вообще то к примеру хэндл окна (даже упрятанный под кучу оберток) или видеопамять это такой же ресурс. Они у вас типа не разу не долгоживущими объектами каким то образом стали? А файлы? А косвенно владеемые ресурсы? из Dispose ручками высвобождаете? Зачем GC нужен если нужно все равно по дереву удаляемых проходить вручную всегда а то беда беда будет? И чем ручное написание using отличается от ручного вызова delete? Автоматика где?
И это вопросы не языка. Это вопросы обеспечения деинициализации объектов по правилам ООП, которые не зависят от языка. Абсолютно очевидно что GC абсолютно бесполезен для имплементации этих правил. Потому что предназначен для решения абсолютно противоположной задачи. При этом имплементация этих правил делает GC абсолютно ненужным, потому что аналогична вызову GC.Collect после каждого изменения ссылки, при этом гораздо эффективнее GC, поскольку не имеет постоянных накладных расходов на содержание живых, только на вынос мертвых который необходимо производить и при наличии GC.euroUK
03.10.2019 21:57Ваш бред в голове сложно комментировать.
Давайте сначала вы ответите на вопрос. Сколько кода в продакшн вы непосредственно написали и когда последний раз это было?Fulcrum013
03.10.2019 22:20-1Ваш бред в голове сложно комментировать.
Когда вы крайний раз правила по которым ООП функциклит в голове освежали? Вы с ними вообще знакомы? А теорию графов изучали? А анализ графов взаимосвязей в вашей задаче когда призоводите до написания кода или после? А то вы похоже вообще просто не в теме что такое ООП и чем задачи управления памятью отличается от задачи управления жизненым циклом и задачи управления взаимосвязями.euroUK
03.10.2019 22:56+1Вы знаете, я код пишу в прод, а не читаю мистические правила времен советских вузов.
DistortNeo
03.10.2019 21:22+1GC этого не умеет от слова совсем.
GC этого не должен уметь по определению. Память не является тем ресурсом, который должен быть обязательно освобождён по выходу из scope. А что должно быть освобождено обязательно — освобождается явно. Сейчас даже scope-based using добавили, чтобы сделать это ещё более удобным.
Я про автоматическое управление жизненным циклом. Про автоматическую деинициализацию объекта при выходе его из скопа/деинициализации содержащего его объекта.
При программировании многопоточных приложений на C++ я на практике сталкивался с ситуациями, когда подобное поведение оказывалось нежелательным, а управление памятью становилось весьма сложным и тяжёлым с нагромождением shared_ptr/weak_ptr и проблемами с циклическими зависимостями. В C# же такой проблемы нет.
Fulcrum013
03.10.2019 22:02-1а управление памятью становилось весьма сложным и тяжёлым с нагромождением shared_ptr/weak_ptr и проблемами с циклическими зависимостями.
ООП не пробовали использовать? В нем проблем с циклическими зависимостями нет.DistortNeo
03.10.2019 22:27+1А причём тут ООП? Ну вот есть два объекта, каждый из которых ссылается на другой. Они сами не удалятся.
Fulcrum013
03.10.2019 22:37-1А причём тут ООП? Ну вот есть два объекта, каждый из которых ссылается на другой. Они сами не удалятся.
Ну дак это уже нарушение правил предметной области. Т.е. сама такая ситуация это уже баг. Потому что деинициализация объектов в таком случае не может быть произведена вовремя. Поэтому правила построения связей такую ситуацию полностью исключают.
В ООП нет понятия нужен/не нужен. Есть понятие может/не может продолжать существование. При этом одной из причин невозможности продолжать существование есть разрыв связи типа копозиция. Т.е. нет препятсвующих удалению. Есть ответсвенные за удаление которые удаляют вместе с собой объекты на которые ссылаются. И смена ответсвенного невозможна, он назначается при создании. А соответсвенно и образоваие такого кольца тоже. При разрыве внешней связи произойдет уничтожение обоих объектов.Kanut
03.10.2019 22:43+1Ну дак это уже нарушение правил предметной области. Т.е. сама такая ситуация это уже баг. Потому что деинициализация объектов в таком случае не может быть произведена вовремя. Поэтому правила построения связей такую ситуацию полностью исключают.
Извините меня но что за чушь вы тут несёте? Два обьекта с ссылками друг на друга встречаются в любом ООП языке сплошь и рядом и никаким багом не являются.
Да возьмите любое банальное parent<->сhild отношение и вот вам уже пример такой пары.Fulcrum013
04.10.2019 00:10-1Извините меня но что за чушь вы тут несёте?
То просто вы не въехали в суть того как это работает в ООП. чилд композирован в парента. т.е он не может существовать без парента. Разрыв этой ссылки приводит к мгновенному и перманентному уничтожению чилда. Кстати так о птичках это не циклическая а двунаправленная ссылка. И по сути в ООП все ссылки двунаправлены. И никакие счетчики не нужны.
Два обьекта с ссылками друг на друга встречаются в любом ООП языке сплошь и рядом и никаким багом не являются.
Багом они станут если оторвутся. Т.е. если дед потеряет ссылку на парента. Но поскольку потертеря этой ссылки по правилам то й же композиции ведет к перманентному удалению парента то и парент и чилд тут же будут удалены.
Вот так кстати все и фурычит в той же дельфе. Все на таких двунаправленных ссылках. И именно это обеспечивает возможности широкого использования биндинга и как следствие преимущественно визуальной разработки бизнеслогики
Kanut
04.10.2019 08:05+1То просто вы не въехали в суть того как это работает в ООП. чилд композирован в парента. т.е он не может существовать без парента. Разрыв этой ссылки приводит к мгновенному и перманентному уничтожению чилда
И снова какой-то бред. У меня совершенно спокойно могут быть ещё и отдельные ссылки на пэрента и на чайлда. Но вот если я их уберу и оставлю только их ссылки на друг друга, то по вашей логике они навсегда останутся в памяти....
Багом они станут если оторвутся.
Происходит сплошь и рядом. Вполне себе умышленно и тоже никаким багом не является…
Fulcrum013
03.10.2019 22:08-2Память не является тем ресурсом, который должен быть обязательно освобождён по выходу из scope
А инстанс который живет в этой памяти должен быть деинициализирован обязательно. Опять же по правилам ООП. Поэтому придется по дереву удаляемых пройти все равно. И гораздо эффективней попутно и буфера в список неиспользуемых занести пока знаем какие, чтобы не сканировать постоянно всех живых.DistortNeo
03.10.2019 22:26+1А инстанс который живет в этой памяти должен быть деинициализирован обязательно
Совершенно не обязательно, если единственный используемый ресурс — это память.
И гораздо эффективней попутно и память удалить пока знаем какую, чтобы не сканировать постоянно всех живых.
Не факт. Удаление из глобальной кучи вотпрямщас дорогое + требуется межпоточная синхронизация.
Fulcrum013
03.10.2019 22:42-1Совершенно не обязательно, если единственный используемый ресурс — это память
А откуда вы знаете какой там ресурс под капотом и какая там вообще под ним глубина дерева композиции объектов и какие агрегации у этого поддерева нужно разорвать при деинициализации? В общем случае об этом знает только сам объект. Именно поэтому и требуется деинициализация всего удаляемого подерева.DistortNeo
03.10.2019 23:00+1Об этом говорит наличие интерфейса IDisposable и намерения программиста по явной очистке ресурсов.
Fulcrum013
03.10.2019 23:11-1Об этом говорит наличие интерфейса IDisposable
Так он у всех абстрактных базовых типов должен быть. Потому как абстрактный предок не может знать что будет под капотом у потомков. А обрабатывается то оный потомок по ссылке на предка.
Fulcrum013
03.10.2019 23:16-1и намерения программиста по явной очистке ресурсов
20-ый год 21-го века. А все ручками делать. В том числе Dispose писать. Не я с такими глупостями еще в прошлом тысячелетии покончил. намучался достаточно на паскакале. Т.е. никакой разницы с полным отсутствием автоматики GC не дает кроме ненужного оверхеда.
Fulcrum013
03.10.2019 23:22-1Только оно очень редкое. Особенно с учетом того что вся мелочь композирована статически, a объекты которые живут на куче вообще по определению долгоживущие.
Fulcrum013
03.10.2019 22:28-1При программировании многопоточных приложений на C++ я на практике сталкивался с ситуациями, когда подобное поведение оказывалось нежелательным,
А почему я с ним не сталкивался? Может потому что параллелить нужно или в режиме разделения ресурсов или в другом месте, иначе проблемы будут в любом случае?
Yuuri
01.10.2019 22:59+3С++ наиболее высокоуровневый язык на сегодняшний день.
Программисты на Haskell, Clojure или F# смотрят на этот комментарий с недоумением.
edwardbailey
01.10.2019 10:08+1nice debate on the comparison between c++ and C#.There are many language comparison we have found in the software industry and why it does matter alot and i think the measure difference between the platforms or language is coding and programming.
eagleivg
01.10.2019 10:24+5Самое странное, что никак не представлен гймдев, где плюсы до сих пор на коне (и не надо мне расказывать про Unity, там на шарпе только логика пишется, движок всё равно на плюсах, а самая частая жалоба на игры на этом движке — тормозит на топовых конфигурациях).
В самом началесрачадискуссии кратко упоминалось — если вам надо быстро разрабатывать — это к шарпу, если вам надо чтобы разработанное быстро работало — это к плюсам. На текущий момент единственный плюс у C++ — это предсказуемое время выполнения, что в геймдеве критично (бюджет времени 16 мс на кадр).
Подробней про это можно посмотреть в серии лекций томских Unigin-овцев: www.youtube.com/playlist?list=PLgeSUiT3pydG7KchiEhjYvwkORh7TSGNiimpwx
01.10.2019 11:18+1Есть подвижки по части переписывания критичной логики с плюсов на сабсет шарпа:
eagleivg
01.10.2019 11:44+1Погуглил, в основном народ не в восторге. Хотя направление (Job => IL => байт-код LLVM => оптимизации => машкод) интересное.
Fulcrum013
03.10.2019 01:06-1А на самом то деле если вам надо чтобы разработать быстрее чем на шарпе и чтобы работало быстро — это опять же к плюсам с соответсвующими фреймверками. А причина срача она в том что Майкрософт подобные фреймверки не осилил. Даже WinForms — результат совместного проекта с Борландом, релизить который Борланд отказался, по причине крайней убогости полученного гибрида по сравнению с нативным предком.
Sigiran
01.10.2019 11:03+4Меня всегда умиляет фраза «язык мультиплатформенный» от разработчиков, которые использую интерпретируемые языки. Как-будто эта мультиплатформенность родилась сама собой.
IvanhoeLab
01.10.2019 12:17+2Больная мозоль.
На работе лежит проект, сделанный аж на Builder C++5. Много форм и элементов, СУБД,fastreport и пр.
Надо его переписать, но не могу сделать выбор. Кроссплатформенность не нужна. Важное — нужен мощный генератор отчетов.
Нынешняя громила Embarcadero Builder пугает. Смотрю в сторону Qt — очень радует он меня, и размер distroDLL в принципе адекватен.
А вот к шарпу отношусь напряженно, отчасти из-за кучи фреймворков и страха совместимости между ними. Мой бинарный код от BCB5 отлично работает на всех Windows и будет работать дальше. А шарп настораживает.
У кого-нибудь был похожий выбор? Спасибо.Dansoid
03.10.2019 15:03Переходи на шарп, 12 лет назад плюнул на Борланд и не жалею.
FastReport прекрасно заменяется этим DevExpress XtraReports
Kanut
03.10.2019 15:21У Microsoft с относительно недавних пор появилась такая штука как .Net-Standard. И как раз для того чтобы решать проблемы совместимости.
Если совсем грубо, то если вы пишите ваш код в библиотеке совместимой с определённой версией .Net-Standard, то он работает на любом фреймворке, который поддерживает эту версию.
PyerK
01.10.2019 12:27Мне кажется что для C# гораздо лучше для сравнения и холиваров подходит Java. Эти два языка имеют похожие парадигмы и идеи и рыночные ниши в которых конкурируют. Это два детища microsoft и oracle которые были созданы в одинаковых условиях конкурентной борьбы.
Но С++ был создан с другими целями, гораздо раньше у него своё мировоззрение и идиомы. С++ не похож на эти два языка. Но на нём можно писать код мало отличимый (благодаря zero cost abstraction и богатому функционалу) от многих других языков.
excoder
01.10.2019 14:00+3Идеализм этот с некоторыми от C++, «убрать макросы», ну come on. Как я без макросов организую себе удобоваримые properties в классах, например? Пофиксите мне язык, добавьте адекватные class properties чтобы без этого вот бесконечного .set_value (a.get_value () + b.get_value()), добавьте named orderless function arguments, чтобы я мог тренировать свою память где-нибудь ещё кроме как привязки аргумента к его имени «на глазок», и проводить вечера с семьёй, а не с перетасовыванием аргументов при рефакторинге — вот тогда поговорим о удалении макросов. А пока я это всё только макросами и могу более-менее организовать, чтобы писать линейный код, а не продираться сквозь завалы тривиального синтаксиса.
PyerK
01.10.2019 15:08+1Я однажды узнал перевода слова get с английского языка. Теперь применять префикс get в методах получения значений морально сложно.
Приведу некоторые почти очевидные примеры:
man.get_married(); bank.get_money();
Во многих библиотеках (например Qt) трендово сейчас называть методы получения свойств так же как и свойство, что повышает читабельность программы особенно среди англоязычных программистов.Dimonkov
01.10.2019 15:47+4Пример с get_married() просто ужасен.
Уже давно все нормальные люди для bool проперти используют is вместо get.
Что лучше, gameObject.GetDisabled() или gameObject.IsDisabled() ?
ИМХО, 2 вариант гораздо лучше читается.
PyerK
01.10.2019 16:26+1Для bool проперти is перфикс — отличный выбор, никто же не спорит. Но ведь это может быть и не булевская переменная, а обьект — ребро социального графа.
Речь о get VS noget.
А get_married() лишь яркий пример который на слуху у многих людей, что бы понять почему get для пропертей плох.Azirel
01.10.2019 17:12+2Для устранения путаницы должно быть так, ИМХО:
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, ну и в прочем учесть
Dimtry44
01.10.2019 17:15+2женить man на woman
Не толерантненько.
man & woman надо заменить на person.
wife на partner.
</sarcasm>Azirel
01.10.2019 17:16-1Вот я хотел это написать, но комментарий отредактировать не получилось.
Так-то стоит обоих наследовать от Person.Azirel
01.10.2019 17:21-1С целью, естественно, максимальной гибкости системы. Туда же и тему выше про многоженство\многомужество, в мире куча разных вариантов, и стоит поддерживать все, тем более, что это "почти бесплатно" с т.з. кода
Azirel
01.10.2019 21:16-1Ну вот, кто-то и комменты минусанул, и анонимно в карму насрал, как положено… явно очень консервативно настроенный гражданин без чувства юмора.
Dimtry44
01.10.2019 17:38Беру свои слова обратно. Я за стандартизацию, а стандарт ISO/IEC 5218 говорит что:
0 = not known,
1 = male,
2 = female,
9 = not applicable
Так что наверное вполне толерантно использовать man & woman. Хотя конечно они в стандарте мину замедленного действия подложили, назначитли 1 для male и 2 для female, выглядит так как будто male лучше чем female. Похоже скоро будет обновление стандарта и придётся bulk update делать.
mayorovp
01.10.2019 17:26Не на partner, а на spouse тогда уж.
И, кстати, толерантность тут ни при чём — с симметричными отношениями попросту проще работать.
excoder
01.10.2019 16:30> Во многих библиотеках (например Qt) трендово сейчас называть методы получения свойств так же как и свойство, что повышает читабельность программы особенно среди англоязычных программистов.
Yes. От безысходности. Но работал довольно давно с библиотекой, там .married() ещё возвращало ссылку на значение вместо поддержки тривиальных сеттеров, так что можно было .married() = false;. С тех пор косо посматриваю на безпрефиксные геттеры и сеттеры. Ну а проблем расширить C# при этом никогда не было: named parameters в C# 4, properties изначально, и т.д. и т.п. (Сам пишу 90% времени на С++).PyerK
01.10.2019 16:36Да, надо геттеры делать константными, что также будет ожидаемо для пользователей API. Иначе возможны гораздо более странные примеры.
math_coder
01.10.2019 19:32От безысходности.
А почему не просто от разумности? Какой-то идиот когда-то придумал писать
get_xxx()
вместо простоxxx()
и все за ним повторяют. А эти просто не стали.
properties изначально
Только лучше ими по возможности не пользоваться. Так как properties имеют сильно расширенную семантику по сравнению с филдами и методами: property descriptors и всё что через них работает. Если я встречаю где-нибудь в десктопной программе property вместо метода, я вынужден искать, нет ли где на неё binding'а или сериализации или ещё чего-то такого.
excoder
02.10.2019 00:14Соглашусь! Реализация адекватных 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(); }
DistortNeo
01.10.2019 16:12добавьте named orderless function arguments
А ещё отдельный котёл в аду должен быть предусмотрен для того, кто решил, что возможность опускания имён параметров в объявлении функций — это нормально.
void some_function(int, int, int);
PyerK
01.10.2019 16:31А ещё отдельный котёл в аду должен быть предусмотрен для того, кто решил, что возможность опускания имён параметров в объявлении функций — это нормально.
А если это tag dispatch?
Там не принято именовать фейковые аргументы. Варнинги одна из причин.DistortNeo
01.10.2019 16:44Если это внутренний код библиотеки, не предназначенный для чтения её пользователем, то никаких проблем. Но когда такое пролазит в публичный интерфейс, то теряется самодокументированность кода.
PyerK
01.10.2019 17:00+3Фича языка от этого никуда не денется.
Да, в C++ есть многое, что не нравится многим другим.
И ктото, возможно, считает также что авторы UB или aliasing`а или Elvis operator`а должны быть к том же котле.
Особенно есть множество фич которые можно использовать во вред или неправильно. Но это не повод обижать авторов какой то фичи, а повод задуматься о причине по которой она появилась в языке.
Так же все эти фичи делают C++ таким какой он есть, не похожем на все остальные.Fulcrum013
03.10.2019 04:29+1Есть два вида языков. Одни все ругают, на других никто не пишет. (с) Бьярне Страуструп.
0xd34df00d
01.10.2019 21:01-3Если вам для документирования кода нужны имена переменных, то вы ошиблись с типами.
0xd34df00d
03.10.2019 18:57Похоже, стоит развернуть свою мысль подробнее.
Так вот, если у вас есть функция
foo(int, int, int);
то имена не помогут, потому что, среди прочего:
- Имена не видно в точке вызова функций: пусть у вас есть
foo(42, 3600, 29)
илиfoo(bar(), baz(), meh())
, толку с имён-то? - Имена не защищают от опечаток.
foo(secs, life, ack(3, 2))
никак не отличается отfoo(life, secs, ack(3, 2))
с точки зрения компилятора.
2а. Если вы вдруг поменяете API и порядок/семантику аргументов, то компилятор тоже не даст вам по рукам. - Имена не дают полной информации.
int time
— это что? Время в секундах? В миллисекундах? Уже 8 лет как естьstd::chrono
, например.
Kanut
03.10.2019 19:06Имена не видно в точке вызова функций
Это от IDE зависит. В случае с С# и VS имена аргументов как раз видно в точке вызова.
Имена не дают полной информации. int time — это что?
Они дают больше информации. Другое дело что имена надо тоже правильно давать.
Если вы вдруг поменяете API и порядок/семантику аргументов, то компилятор тоже не даст вам по рукам.
Поэтому когда аргументов много и/или есть относительно высокий шанс спутать их порядок, то рекомендуется использовать DTO. Это проблему целиком не решает, но обычно уменьшает вероятность что-то напутать.
0xd34df00d
03.10.2019 20:34Это от 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 — это тип, а значит, моё исходное утверждение в силе :)
Kanut
03.10.2019 20:49А пуллреквесты на гитхабе (возможно, своём тырпрайзном) или фабрикаторе вы тоже в VS ревьювите? Или там, не знаю, git blame какой-нибудь.
Хороший вопрос. Никогда не обращал внимания есть там это или нет:)
Но даже если и нет во время ревью, то как минимум в разработке это есть и помогает.
И вы же не будете утверждать, что start_periodic_digging(int period_in_msecs, int start_time_since_1970, int length_in_km) лучше предыдущего варианта без имён переменных?
Это конечно достаточно субъективно и вопрос привычки. Но могу сказать с тех пор как мы среди всего прочего стали следить за более-менее "говорящими" именами методов, переменных и параметров, то лично мне работать стало гораздо удобнее.
Только имена вы даёте на порядок-другой чаще, чем создаёте новые типы, поэтому и глаз замыливается, и лениться более охота.
Тоже кстати вопрос привычки. Поначалу было сложно и часто приходилось размышлять над подходящим именем. Сейчас уже всё как-то на автомате происходит.
Но DTO — это тип, а значит, моё исходное утверждение в силе :)
Ок, тут не поспоришь, пункт за вами :)
mayorovp
03.10.2019 19:09Подставим вместо
foo
какой-нибудьoperator -
. Упс, кажется, все эти возражения уже не так хорошо смотрятся :-)0xd34df00d
03.10.2019 20:35Хм, а почему?
Тем более, в С-подобных языках у вас не так много операторов, и свои создавать нельзя.
- Имена не видно в точке вызова функций: пусть у вас есть
Azirel
01.10.2019 17:38Сигнатура (int, int, int) вообще "не очень" по сути своей, там уже явно тянет отдельной структурой Params.
DistortNeo
02.10.2019 14:58Генерить абстракцию на каждый чих — тоже не лучшая идея.
Azirel
02.10.2019 16:25Зависит от конкретной ситуации и требований. С методом, допустим, принимающим восемь строк очень неудобно и ошибкоопасно работать — а это случай из реальной практики. Обертка всего этого в DTO убрала кучу «случайных» ошибок.
DistortNeo
02.10.2019 20:16А мы и не говорим о функциях, принимающих восемь параметров. Разумный максимум — 3-4 параметра. Имеет ли смысл заворачивать их в DTO — большой вопрос хотя бы из соображений удобства вызова функций и эффективности (соглашения о вызовах, передача аргументов через регистры на x64 архитектуре).
Azirel
02.10.2019 20:233-4 однотипных — «ну неудобно». С т.з. производительности, конечно, нужно смотреть в каждом конкретном случае. В том же C++ влияние на производительность от «дополнительных DTO» — гораздо сильнее, чем в managed-языках, но ключевой момент именно в балансе «удобство\эффективность\производительность», в зависимости от конкретных целей и задач.
mezastel
02.10.2019 09:45+1Вы сами ответили на свой вопрос: чтобы получить удобоваримые properties, они должны быть в языке, как они сделаны в C#. Макросы — это временная заглушка для разных проблем, которые нужно решать правильно, а не «как получилось».
Fulcrum013
03.10.2019 01:01-1Та properties есть везде кроме стандарта. А в стандарте их нет только потому что любой стандартизированный/нативный для ядра языка формат будет ущербный по сравнению с тем что можно запилить на шаблонах за несколько часов.
MayRiv
01.10.2019 14:01+7Дмитрий: Ну, zero cost abstraction — это ассемблер. Если мы хотим вообще zero cost abstraction, надо писать всё на ассемблере.
Ребят, после этой цитаты хоть кто-то серьёзно относится к этой дискуссии?
noktigula
01.10.2019 15:00+1«Всем известно, что нет ничего глупее споров «какой язык лучше»»
@
«Давайте устроим спор какой язык лучше»
euroUK
01.10.2019 15:02+2Мне кажется, что сама попытка сравнить некорректная.
Шарпы — это язык общего назначения. С развитием Blazor и Core он позволяет писать на одном стеке хоть под браузер, хоть для сервера на Линукс. Это удобно тем, что позволяет использовать одинаковые библиотеки, шарить модели и логику и эффективнее использовать разработчиков между различными частями проектов. И хотя дотнет сделал гигантский шаг вперед в производительности с Core и аппаратными инструкциями, это все еще очень быстрая платформа общего назначения.
Плюсы — это язык специального назначения сейчас по факту. В основном он используется для задач близких к железу или требующих серьезных оптимизаций. Он быстрее, сложнее и дает больше контроля, но требует совершенного иного уровня подготовки и кругозора разраба.
Соответственно, никто не будет писать промышленный веб-портал helpdesk на плюсах, ибо затраты на разработку никогда не окупятся выигрышем в железе. И наоборот, никто (почти) не будет пытаться писать драйвера на C# cosmOS Поэтому что тут сравнивать, я не знаю.
П.С. Что касается обучения, то очевидно, текущий подход устарел. Нет никакого смысла учить людей пузырьковой сортировке потому что обычное программирование давно ушло от решения низкоуровневых задач к высокоуровневым. Я думаю 99% Дотнет разрабов понятия не имеют, как под капотом в Linq сортируются массивы, что не мешает им писать хороший и быстрый код. Алгоритмы сортировки и их реализация, тонкости размещения объектов в стэке нужны только компьютерным специальностям (а программирование у нас учат все технические, а не только программисты) и то, после того, как они научатся использовать стандартные фреймворки.
Я бы сейчас бы учил бы людей как раз на C#:
1) Основам синтаксиса
2) Правилам оформления кода
3) Программированию вида Asp.Net Core Blazor в самом простейшем виде
4) Умению находить и использовать готовые пакеты (а-ля выгрузку в эксель и логирование)
Такой курс позволил бы иметь готовые проекты, немного разобраться в экосистеме и не утонуть в магии указателей. Так как я преподавал даже не C++, а Дельфи, и люди уже не понимали что и как. И вот когда с простейшими вещами проблем не будет, вот тут уже можно рассказывать, а как оно на самом деле происходит.Fulcrum013
03.10.2019 01:34-3Вы ничего не перепутали? Язык с GC универсальным быть не может по определению. Соответсвенно шарп — это узконишевый язык, основное назначение которого — кастомизация кодом сборок компонентов WinForms/WPF. При этом шарп имеет принципиальные противопоказания к применению в подавляющем большинстве задач индустрии, особенно в наиболее актуальных на сегодняшний день — робототехнике и промавтоматике.
А вот плюсы — это таки универсальный язык по определению, и годен к применению в любой сфере.DistortNeo
03.10.2019 01:42+1Подавляющее большинство программирования — это backend, frontend, всякий банковский софт и прочий кровавый энтерпрайз. А вот робототехника и промавтоматика — это нишевые области.
Fulcrum013
03.10.2019 02:30-3Да что вы. Реальный экономический выхлоп дают таки только робототехника промавтоматика и счет по наукам. Вспомогательным является учет, в т.ч. банковский. И даже при том что в этих сферах работает 10% от общего количества разрабов, это и есть 100% разрабов с профессиональным образованием, которые и решают 99% задач индустрии вообще. Все же остальные казуалочки и социалочки — это сфера личного потребления и соответсвенно не более 1% задач и потока финансов индустрии, а соответственно и натягивают туда неквалифицированных разрабов, пытаясь скомпенсировать качество количеством. Вот как раз для таких шарп и предназначен. И именно поэтому основан на яве, которой моск в американских школах насилуют всем поголовно, И Майкрософт прекрасно понимали в исходе абсурдность пытаться создать на этой ошибке природы каких либо профессиональных средств разработки. Но нужна был им как раз замена ворд, эксель и визуал бейсика, позиционируемого как средства для мелкой кастомизации готового софта и создания мелких утилит, производимых непрофессионалами.
phillennium Автор
03.10.2019 09:45+3Сфера личного потребления — это 1% потока финансов индустрии
Поскольку в развитых странах на сферу услуг приходится 70-80% всей экономики, было бы очень любопытно увидеть какие-нибудь источники, подтверждающие ваши слова о «1% потока финансов».
Siemargl
03.10.2019 10:45+1Ну в промавтоматике языки общего назначения используются редко. В основе там iso 61131.
А вот робототехника это эмбеддед со всем вытекающими на С/С++.
euroUK
03.10.2019 10:48+3Ваша реакция на C# неадекватна, при том, что совершенно точно вы не писали на нем годов с 2005х, т.к. ваши представления о производительности, сборщике мусора и прочем явно с тех пор.
Кроме того, ваше восприятие рынка также неадекватно. 95% софта — это как раз средства автоматизации управления предприятиями, банковский софт и прочие сайтики-визитки. Именно для этого и нужен C#. Я вот взял, и построил простенький сайт с нуля на Asp.Net Blazor за день. При этом у меня и с базой работа, и логирование, и бизнес-логика и UI. По факту — готовый проект. Жрет, если правильно работать с ORM порядка 100-120мб памяти с одновременной работой 30 пользователей. А если добавить кэширование, то web-api может десятки тысяч запросов в секунду держать.
А теперь, внимание вопрос. Сколько времени у вас займет написать такое на C++? Что бы и с базой работало, и чтобы логи были, чтобы шаблонизатор был для UI и чтобы перформанс был выше, чем на C#? Ну и чтобы это все можно было поддерживать и было читабельно. За неделю управитесь? Или вам месяц нужен?
Еще раз, платформа и язык общего назначения — это такая платформа, которая позволяет решать 90% задач дешево и эффективно. Я на ассемблере могу написать вообще все, но он никаким боком не будет общего назначения, так как сложно, дорого и долго.Groramar
03.10.2019 13:22Все так. Делфай, к слову, тоже получил нормальные Web библиотеки (UniGUI, TMS Web Core) — все быстро, удобно и просто — накидал формочки, воткнул коннекты к базе, и через день у тебя готовое веб приложение на 5-10 форм. Не нужно вникать в JS. Не нужно делать связку бэк <> фронт, все максимально само. Можно и какой-то ORM добавить — mORMot, например. Тогда и SQL нужен постольку.
Fulcrum013
03.10.2019 19:04-2Что бы и с базой работало,
Для этого код писать не надо от слова совсем.
и чтобы логи были,
Вы считаете трудной задачей заменить cout на другое название а «Hello World» на другую строку? Все с вами ясно.
чтобы шаблонизатор был для UI
Подробнее можете рассказать что вы под этим понимаете?
чтобы перформанс был выше, чем на C#
Знаете есть такое сравнение — тормозит как скайп. Или хотите сказать скайп не шарпом изуродовали?
За неделю управитесь? Или вам месяц нужен?
Вы главное не забывайте что C# builder aka WinForms это настолько жалкий обрубок Дельфы и С++ Builder что борланд который его делал просто отказался участвовать в релизе. Причем обрубок именно в продуктивности именно создания средств учета. Ну и еще один такой момент не путайте языки и фреймверки это две большие разницы. Да и вам же в первую очередь контраргумент. Потому что именно в плане фреймверка именно визуальной разработки именно средств учета/БД шарп и сливает по определению. При этом у шарпа он один. А у плюсов их много.Chaos_Optima
03.10.2019 19:09+1Знаете есть такое сравнение — тормозит как скайп. Или хотите сказать скайп не шарпом изуродовали?
Ядро Скайпа на С++, гуи старой версии на Delphi а новой версии на electron, так что да C# тут непричём
euroUK
03.10.2019 21:48+1Для этого код писать не надо от слова совсем.
А как у вас 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.0viordash
03.10.2019 22:54+1>>Короче поток бреда такой, что я даже не знаю, как это комментировать.
зато это бред уже третий день развлекает, спасибо и крепитесь :)
Fulcrum013
03.10.2019 19:15Кроме того, ваше восприятие рынка также неадекватно. 95% софта — это как раз средства автоматизации управления предприятиями, банковский софт и прочие сайтики-визитки
Оглянитесь вокруг. Наиболее распространенный софт это тот который управляет коммутацией фаз у вас в лампочке. Дальше по распространенности идет тот который управляет вашими холодильником микроволновкой, контроллером впрыскав автомобиле и т.д. Дальше тот который управляет изготовлением всего этого на станках. Потом тот при помощи которого все это проэктируют. Ну а потом тот на котором производят научные исследования для создания всего этого. И только уже потом идет учетный софт мизерная часть которого банковский. Если вы кроме сайтов-визиток ничего не видели это не значит что сайты визитки самые распространенные.
math_coder
03.10.2019 11:02Кажется, Царя проапгрейдили до Царь++.
0xd34df00d
03.10.2019 18:47А что за Царь? А то вижу уже второй или третий раз отсылку в очень характерных контекстах.
math_coder
04.10.2019 07:30Да был (и в каком-то виде есть) такой персонаж на linux.org.ru. С характерным стилем и тезисами. А также клоны и подражатели. Один из основных тезисов (как он мне запомнился) такой: "всё можно и нужно писать на Си, а что нельзя писать на Си, то и не нужно".
Но он (как виртуальная мультиличность) не только и столько на абстрактные темы вещал, а в обсуждении конкретики участвовал, вещая дурь вперемешку с разумными и верными утверждениями, и с невероятным апломбом по типу "вы все ламерьё, вебнули, обезъяны, а я — Царь сишечки".
Вот пример: https://www.linux.org.ru/forum/development/15256164?cid=15260615
Kanut
03.10.2019 11:20+2Да что вы. Реальный экономический выхлоп дают таки только робототехника промавтоматика и счет по наукам. Вспомогательным является учет, в т.ч. банковский. И даже при том что в этих сферах работает 10% от общего количества разрабов, это и есть 100% разрабов с профессиональным образованием, которые и решают 99% задач индустрии вообще. Все же остальные казуалочки и социалочки — это сфера личного потребления и соответсвенно не более 1% задач и потока финансов индустрии
Ну вот смотрите: я работаю на транспортный концерн. За то время что я на него работаю мы ввели в строй систему оптимизации маршрутов и загрузки грузовиков. По прикидкам концерна это минимум 4-5% сэкономленных километров. А местами и все 10%. Звучит может быть немного, но если взять тысячи грузовиков и миллионы(а то и миллиарды) километров, то получается совсем неплохой "экономический выхлоп".
Ещё мы перевели почти всю сопроводительную документацию с бумаги в дигиталку. А это тонны сэкономленной бумаги и огромное количество сэкономленных человекочасов. Тоже никто не жалуется.
И всё это на "казуальном сишарпе". Так что прежде чем подобные заявления делать было бы неплохо сначала хотя бы чуть-чуть проинформироваться.
Fulcrum013
03.10.2019 19:20-1И всё это на «казуальном сишарпе»
Только вот весь остальной мир делает это на нативных языках. Потому что они позволяют иметь гораздо более продуктивные в этом плане фреймверки с гораздо более развитыми средствами визуальной разработки.Kanut
03.10.2019 19:28Если у вас есть статистика, то я с удовольствием на неё посмотрю. А так вы уж извините, но это для меня больше похоже на какие-то ваши личные фантазии.
П.С. И особо интересно мне было бы посмотреть на процент написанных иключительно на нативном языке "экосистем", включающих в себя в том числе и десктоп-приложения, B2B сервисы, веб и мобильные приложения.
Siemargl
03.10.2019 19:52-2Все очень просто. Ты разрабатываешь Великую Бухгалтерскую Программу.
При этом сидишь за компьютером, БИОС которого написан на Си, ОС на Си, все драйвера на С, IDE тоже возможно на Си. Итого статистика 1:10 =)
И стул, который пригорает, тоже спроектирован в написанном на С CAD'e )))Kanut
03.10.2019 20:03+1Это уже другое и я нигде вроде бы не утверждал что нативные языки вообще не нужны или не используется.
Fulcrum013
03.10.2019 20:00-1И особо интересно мне было бы посмотреть на процент написанных иключительно на нативном языке «экосистем», включающих в себя в том числе и десктоп-приложения
Ну есть статистика по поддерживаемым лицензиям на средства разработки. Для Дельфы/билдера это 500k действующих лицензий. Т.е. практически весь сектор внутрикорпоративного софта крупных корпораций и его веб-мосты. Таких как Сименс, Самсунг и т.д.
И по продуктивности есть кое какая инфа. К примеру среднестатический клиент-банк для корпоративного клиента (это с сервером и рабочей группой на стороне клиента мультиподписями синхронизацией баз, процессингом, его изоляцией как внутренней так и внешней, завязкой на аккаунт-менеджеров, подсистемой администрирования ключей и т.д. мелочью) делается на дельфе или билдере двумя разрабами среднего пошиба месяца за два-три.
И по шарпу с жабой есть интересные наблюдения. Значит есть тут три индустриальных гиганта в городе. Два металлургических и один машиностроительный. Так вот пришли мы на практику в 98-ом на один из них у них там как раз новый отдел — новую ERP R3 внедряют. Там типа сверхпродуктивный язык кастомизации новейший ява. Ну договорились что друг другу не мешаем и разошлись (мне как бы на свой машиностроительный гигант бежать надо было к самому группа практикантов с технаря должна прийти была). Ну в общем к 2002-ому где то так внедрение полным ходом шло на всех трех гигантах. Потом там язык поменяли на новейший шарп и винформз все эти три отдела возрадовались наконец то мы ее докастамизируем (одним из этих отделов к тому времени уже мой одногрупник руководил так шо видел как они там типа рады были по самые немогу). Ну в общем суть в том что на металлургических гигантах ее до сих пор полным ходом внедряют. А машиностроительный 5 лет назад обанкротился и закрылся.Kanut
03.10.2019 20:11+1Ну есть статистика по поддерживаемым лицензиям на средства разработки
Посмотреть на неё можно где-то?
Для Дельфы/билдера это 500k действующих лицензий.
И что это должно доказывать? Особенно в контексте моего вопроса?
И по продуктивности есть кое какая инфа. К примеру среднестатический клиент-банк для корпоративного клиента (это с сервером и рабочей группой на стороне клиента мультиподписями синхронизацией баз и т.д.) делается на дельфе или билдере двумя разрабами среднего пошиба месяца за два.
А это то вообще причём? И если уж, то за какое время такое же делается "двумя разрабами среднего пошиба" на других языках? Ну для сравнения.
Fulcrum013
03.10.2019 20:30-2И если уж, то за какое время такое же делается «двумя разрабами среднего пошиба» на других языках?
Это в первую очередь вопрос не языка. Это вопрос умения фреймверка работать с созданием системы учета по принципу zero code. Т.е. преимущественно визуальная разработка в первую очередь бизнес-логики работы с БД. Т.е. используется факт что оформление информационной постановки на компе по телодвижениям почти на 100% совпадает с реализацией. И вот ни ява ни шарп подобный принцип визуальной разработки бизнес-логики потянуть не смогли. Как Борланд не старались их этому обучить, даже в случае шарпа совместно с майкрософтом. GC мешает. Он лишний в ООП.Kanut
03.10.2019 20:38+1Это в первую очередь вопрос не языка.
Да неважно вопрос чего это в первую очередь. Приведите сравнение с альтернативными вариантами. Тогда это можно обсуждать.
П.С. Пока я если честно вижу кучу какой-то отсебятины и перепрыгивания с одного на другое. И слабо понимаю о чём это, зачем это и какое отношение это имеет к обсуждаемой теме.
Fulcrum013
03.10.2019 20:50-1Ну вот соседний с ними банк уже лет 10 все допиливает и допиливает свой клиент-банк на яве целыми двумя офисами в двух городах. Ну он правда на частного клиента ориентирован с одной стороны проще с другой вроде как объемней с третьей интеграцию с внутренними системами клиента и мультиподписи обеспечивать не надо, c четвертой интерфейс клиентский у них по определению веб а из html формат описания гуя никакой. Ну кое что более менее внятное оформилось. но как бы элементарных поисков нет хотя писал им на этот счет еще лет 5 назад (сам пользуюсь неудобно) сказали дада надо сделать. Ну как бы эту кухню я изнутри не видел. Но насколько понимаю срамо-агилом во всю воняет.
Kanut
03.10.2019 21:00+1Ну вот соседний с ними банк уже лет 10 все допиливает и допиливает свой клиент-банк на яве целыми двумя офисами в двух городах.
И опять же: что это должно доказывать? И если я сейчас приведу пример какой-нибудь шарашкиной конторы где на С++ ничего толкового написать не могут, то это по вашему будет означать несостоятельность C++?
Fulcrum013
03.10.2019 21:21-1Хорошо. Давайте по другому. Потому что так можно все что угодно моя твоя не понимает. Надо или одной компании продукты сравнивать на обоих языках, причем одного направления. Но это бессмысленно. Потому что весовая категория разная. Единственное где так получается сравнить — это сама винформз с VCL. VCL практически монополист в своей нише. WinForms разработчик в релизе участвовать отказался. Релиз Delphi.NET тоже закончился эпическим фейлом. Настолько куцей и непродуктивной была по сравнению с нативной. Точно так же как и майкрософтовская С++.NET живет только потому что MS конкуренцию в нативном проиграл с треском а менеджед купил — т.е. понял что не его уровня задача и даже для себя не может сделать, а другого средства доступа к WinForms нет.
Или конкректно с графами и диаграмами показывать почему GC без ручного решения задачи управления взаимосвязями не способен обеспечить работу взаимосвязей по правилам ООП. Что и не позволяет вести на нем полноценную ООП разработку. А соответственно ни высокопродуктивных средствпреимущественно визуальной разработки бизнеслогики использовать не может, ни продуктивности разработки кода сравнимой с нативными языками, а особенно имеющими современные средства автоматики, не будет. Ей богу как будто на третьем курсе теорию графов не проходили и правила взаимосвязей в ООП — композиции и агрегации тоже никогда не слышали.Kanut
03.10.2019 21:32+1Единственное где так получается сравнить — это сама винформз с VCL.
И о чём нам именно это сравнение должно говорить? И если вы не можете нормально сравнивать и/или у вас нет адекватной информации, то зачем тогда ваши громкие заявления? И на чём они тогда вообще базируются?
Fulcrum013
04.10.2019 01:26-1И о чём нам именно это сравнение должно говорить?
WinForms — примитивная формошлепка. Вся бизнеслогика кодом включая доступ к БД.
VCL — формошлепная часть 10% остальные 90% — разработка бизнес-логики по принципу no code
Fulcrum013
03.10.2019 20:40-3Ну считайте дважды два. В мире порядка 20 миллионов разрабов всего. из них с в/о по специальности порядка 2 миллионов. Ни в сектор корпоративного а тем более банковского учета, ни тем более в сектор автоматики без в/о не пустят. примерно 3/4 работают в сфере АСУТП, САПР и счета по наукам. и примерно оставшиеся пол миллиона в корпоративном учете. С учетом того что ни САПР на билдере не делают (ну там на вижак сели плотно еще в начале 90-х, вернее тогда он назывался MSC++), и в АСУТП если и пригоден фреймверк то очень ограниченно на выделенных терминалах. Ну в счете по наукам каую то часть лицензий юзают точно. Билдер в основном сюда позиционируется, в системы учета в основном дельфа. А остальные то где могут быть? А особенно если абсолютно точно известно что Борланд и потом Эмбаркадеро именно на крупные канторы ориентировано, а на мелочь им даже судя по их техническим решениям глубоко пофиг? Ну и продлевают эти лицензии как понимаете не для того чтобы они на полочках пылились.
Groramar
03.10.2019 20:34Для Дельфы/билдера это 500k действующих лицензий
Более трех миллионов, если что.Fulcrum013
03.10.2019 20:58Более трех миллионов, если что.
ну более трех миллионов то и прибрехать местами диллеры могли. или посчитать всех клиентов за все существование в том числе вышедших студенческих в те времена когда комьюнити-лицензии не было. А вот цифра более 500k. кототрую на эмбаркадере как то видел — ну это из серии точно не меньше. Хотя с Германии знакомые рассказывали — дельфа/билдер/плюсы/ада — другое не котируется в том числе в универах так и говорят — натив а то работу не найдете. У них там правда ситуация совсем не как у нас.Groramar
03.10.2019 22:38Ну вот что бы далеко не ходить:
www.embarcadero.com/ru/products/delphi/starter/free-download
Выбор более чем 3 миллионов разработчиков во всем мире
Kanut
03.10.2019 22:54+1Хотя с Германии знакомые рассказывали — дельфа/билдер/плюсы/ада — другое не котируется в том числе в универах так и говорят — натив а то работу не найдете. У них там правда ситуация совсем не как у нас.
Вы знаете это очень интересно выглядит когда кто-то, со слов каких-то мифических знакомых, рассказывает людям живущим и работающим в Германии, что они оказывается работу не найдут...
И я вам ещё раз скажу: чушь вы полную несёте. В Германии сейчас нужны программисты практически на всех языках. И вот вам кстати для примера информация на тему самых востребованных программистов и языков:
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/
Надеюсь поймёте что там написано. В крайнем случае гугл-транслэйтор вам в помощь или друзей попросите перевести.
0xd34df00d
03.10.2019 20:36Ну есть статистика по поддерживаемым лицензиям на средства разработки. Для Дельфы/билдера это 500k действующих лицензий. Т.е. практически весь сектор внутрикорпоративного софта крупных корпораций и его веб-мосты.
Как эта статистика учитывает лицензии на компиляторы gcc или clang и такие популярные средства разработки на C++, как голый vim?
Fulcrum013
03.10.2019 21:04-1А при чем тут билдер к gcc? У нас же разговор пошел про высоко продуктивные фреймверки? Ну под плюсы их разных хватает. В том числе под стандартные плюсы. И все куда попродуктивней WinForms/WPF будут которыми шарп ограничен.
А это только про эмаркадеру. Ее фреймверк ее расширений требует. другие компиляторы с ним работать не будут. Хотя у самого него компилятор на основе __clang сделан.
Но тут сравнение с шарпом и винформзом очень показательное. Одного папши детки то.
VanKrock
01.10.2019 17:43-1Очень странный спор, когда коснулись GPGPU даже не упомянули про OpenCL хотя он как раз кроссплатформенный, что может даже работать на CPU. Но вообще я все же за C# так как он покрывает очень много бизнес кейсов и гораздо удобен для них нежели С++. C# проще учить и на нем проще делать отладку. А во многих нишах, где требуется более низкоуровневое программирование, высокая производительность я бы использовал чистый Си или Rust. Таким образом я не вижу для каких задач С++ подходил бы лучше чем C#/Java, Си/Rust, TypeScript, python.
PyerK
01.10.2019 17:57+4Таким образом я не вижу для каких задач С++ подходил бы лучше чем C#/Java, Си/Rust, TypeScript, python.
А если мыслить категориями не задач, а рыночными нишами?
Сколько на этой неделе можно нанять разработчиков на Rust?
Какой процент разработчиков на python готовы писать и отвечать за написанное в многопоточной среде?
Сколько можно найти C# девелоперов с многолетним опытом в эмбеддед и линукс?
Так или иначе рыночные ниши фрагментировались както, библиотеки в предметных областях написались в определенных исторических условиях, специалисты выучились и набрались опыта. Решать задачи нестандартными методами\языками\специалистами из других областей можно, но дорого.Azirel
01.10.2019 18:03"Что и требовалось доказать" — язык нужно выбирать под задачу. Подавляющее большинство задач "общего назначения" — лучше решаются на C#, чем на C++, т.к. C++ сейчас является всё-таки языком "местного назначения".
Он рвёт в клочья в определенном наборе задач, но слишком сильно удорожает разработку "in general".
P.S. Сам знаю оба, использую по уместности.PyerK
01.10.2019 19:20+1Он рвёт в клочья в определенном наборе задач, но слишком сильно удорожает разработку «in general».
Да дороже. Сейчас чаще получается рейты у плюсовиков выше, а доступность дешёвых ниже. Но ведь это не проблема языка, а резко возросший спрос рынка. Вот, например, в Киеве зашло около 10 крупных проектов, и спылесосили они всё что было доступно аж до уровня 4000usd по зарплате.
Понятное дело, что многие сферы, включая эмбеддед, перешли на более доступные альтернативы, и писать формочки/мобильные приложения/казуалки готовы на чем угодно только не С++. Шесть лет назад ситуация была сильно противоположная, думаю развитие языка дало сильный стимул рынку.
Fulcrum013
03.10.2019 09:22-2Он рвёт в клочья в определенном наборе задач, но слишком сильно удорожает разработку «in general»
При этом очень сильно снижает TOC.
Подавляющее большинство задач «общего назначения» лучше решаются на C#, чем на C++,
— Ну к примеру ни одного САПР общего назначения на шарпе еще никто не видел. И ни одной СУБД общего назначения. И ни одного вебсервера общего назначения. И ни одной оси общего назначения. И не увидят никогда. Потому что если шарп таки довести до ума и сделать таки универсальным языком то получатся таки плюсы а не что то другое.
VanKrock
01.10.2019 18:24-1Вы так здорово скинули Си со счетов. Embeded лучше писать на Си, а прототипировать на python. Что то многопоточное очень удобно пишется на Go. Разработчики на Rust на рынке присутствуют в принципе. С++ хорошо подходит там, где много готового кода на С++ нет смысла переходить на что то еще. То есть С++ может в принципе неплохо справится со всем, но слишком немного задач, где бы он подходил лучше всего.
PyerK
01.10.2019 19:04+3Не понятно почему 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% изменений, но которые дифф не может вообще никак сопоставить — это ад, и порой проще запортировать заново.
IRainman
02.10.2019 15:38Если это размер бинарника, то с отключенным rtti + exceptions отличия не должны быть существенно заметны для идентичного кода.
Притом во многих случаях на C++ даже код на C компилируется в меньшее по размеру и работает быстрее ;)
0xd34df00d
01.10.2019 21:05-1Что то многопоточное очень удобно пишется на Go.
Забавно, как раз вчера статья была.
KanuTaH
01.10.2019 19:25+2Вот пример:
https://inobitec.com/products/dicomviewer/
Особенности: высокие требования к производительности, расчет как на CPU, так и на GPU с помощью OpenCL или CUDA, по-максимуму общая кодовая база как для разных десктопных платформ (Windows, Linux, MacOS X), так и мобильных (iOS, Android) — понятное дело, для мобильных в несколько облегчённом виде, но тем не менее. Сейчас это написано на C++ с использованием Qt. Как бы вы это писали на C# и с помощью чего?
VanKrock
01.10.2019 20:42Посыпаю голову пеплом, свою же область, на что учился, я и позабыл. Да, компьютерная графика всецело за С++. Хотя пока учился, то делал все из той же области на C# используя библиотечку OpenTK (OpenCL + OpenGL + OpenAL) кроссплатформенности тогда конечно же не было, сейчас вроде можно сделать и кроссплатворменно. Но С++ тут все же должен быть удобнее.
mezastel
02.10.2019 09:49Я его не упомянаю потому что OpenCL существенно хуже CUDA по всем параметрам кроме проприетарности. Кода в 2 раза больше, инструменты отладки «как повезет» (CUDA Toolkit шикарный) и идея о том что один и тот же код можно писать и запускать и там и там — это идиллия, т.к. по факту все алгоритмы приходится все равно переписывать в стиле SIMT, а если нужно что-то дернуть из C++, никто не мешает пометить функцию как __device__ __host__.
Groramar
01.10.2019 19:23+2Delphi/Lazarus в помощь: кроссплатформенность, быстрая сборка, второй работает на чем угодно вплоть до утюгов :) Интерефейсных компонент хватает, не нужно одним Qt ограничиваться (к слову — под него Lazarus) тоже собирает бинари. На распебери Лазарь не только собирает бинари но и среда работает.
Siemargl
01.10.2019 21:16А еще Лазарус обгоняет Питон!
serbod
03.10.2019 11:33-1Lazarus и Delphi это IDE. А язык называется Pascal. По возможностям он не отличается от C/C++, а по безопасности и удобству близок к C#. Производительность кода ограничена только качеством компилятора. Впрочем, можно прямо в коде использовать ассемблер, не полагаясь на компилятор.
DistortNeo
03.10.2019 11:57Delphi — это и язык, и IDE.
Разница между Delphi и Pascal такая же, как между C++ и C.serbod
03.10.2019 12:10Тогда почему у файлов Delphi расширение .pas? =)
math_coder
03.10.2019 12:14DistortNeo прав, язык и самом деле называется Delphi. До определённой версии он назывался Object Pascal, но в Delphi 7 его переименовали в Delphi, так что с тех пор это действительно и IDE, и язык.
serbod
03.10.2019 12:31Формально — да. Хотя, разница между ObjectPascal и Delphi только в автоматическом разыменовывании типизированных указателей. То есть, можно не ставить @ и ^ во многих случаях.
В Lazarus и FreePascal это просто опция компилятора.Siemargl
03.10.2019 20:03Нет такого понятия как ObjectPascal. Есть Паскаль ISO/IEC 10206:1991 и есть недоразумение в виде Дельфи, которое меняется с каждой версией.
По безопасности и удобству он далеко взаду. А качество компилятора FPC описывается фразой «нативный неоптимизирующий компилятор»
Но в целом, надо было просто распознать сарказм вserbod
04.10.2019 11:05Из справки 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++, у которого тоже разные диалекты.
hddscan
03.10.2019 18:29-1У Builder C++ расширение файлов .cpp, у Microsoft C++ расширение файлов тоже .cpp
Удачи с компиляцией Builder в MS Visual Studiomayorovp
03.10.2019 19:13А при чём тут компиляция? Не смотря на приводящую к несовместимости разницу в деталях, это всё еще один язык, С++.
hddscan
03.10.2019 22:15какой смысл несет эта фраза: «это всё еще один язык, С++», если приложение по факту придется портировать из одного C++, в другой С++, для компиляции, а это практически означает, что не все C++ одинаково равны.
hddscan
02.10.2019 00:43+4C# писали в том числи люди из Borland-а.
Отсюда всеми любимые property в C#.
Правда некоторые любят заявлять что Borland мертв и там нет ничего полезного, забывая что много фишек C# это по сути Delphi/BuilderGroramar
02.10.2019 08:48+1Всё так. Шарп многие хорошие вещи позаимствовал. Шарп мне нравится как язык. Не нравится дотнет как платформа. К сожалению, Шарп так и не научили нативной сборке. К слову — даже Лазарус научили для JIT собирать :) А вот наоборот — увы.
kasthack_phoenix
02.10.2019 14:07+1К сожалению, Шарп так и не научили нативной сборке
AOT давно есть, как минимум в Mono и используется активно в приложениях под iOS.
В Core 3.0 есть R2R images — AOT-сборки приложений.
Antervis
01.10.2019 20:08+1Ну, зато виртуальная машина может, например, затюнить код для той или иной архитектуры.
очень странный аргумент. Мы можем скомпилировать плюсы в байткод вм и выполнять на целевой платформе. О состоятельности такого подхода можно судить в первую очередь по его популярности.
arseniy_artmind
01.10.2019 21:35-6Когда-то разрабатывал только на С++ и был большим фанатом языка, писал для 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#, если его допилили за эти годы. Но никак не в плюсы.Siemargl
01.10.2019 21:48+1нужно начать, а не плакать об упущенных возможностях…
тогда это,… кругозор появитсяarseniy_artmind
02.10.2019 06:14+1Начать что?
Благодаря тому, что я выучил что-то совсем другое и избавился от ощущения, что С++ это центр вселенной, я работаю на заказчиков по всему миру, и я очень доволен. Уровень заработков у меня возрос в несколько раз. Где упущенные возможности-то? :)
KanuTaH
01.10.2019 22:08+4А в javascript вдруг оказалось, что 90% всех моих логических задач решает то, что функция — это одновременно класс, объект, замыкание и экземпляр. То есть всего одна гибкая языковая конструкция решает все задачи.
Только вы забыли упомянуть цену этого.
Добавьте к этому async/await для «многопоточности», для понимания которой кроме этих двух слов ничего не нужно.
Ну еще бы, ведь к многопоточности это не имеет абсолютно никакого отношения. Расскажите мне, пожалуйста, как с помощью async/await распараллелить вычислительную задачу.arseniy_artmind
02.10.2019 06:54-3Только вы забыли упомянуть цену этого.
Да очень просто цена считается. Вот есть компания, ей нужно обеспечить бизнес процесс для сотрудников. Ее интерес — чтобы сотрудники имели заданный интерфейс взаимодействия друг с другом, чтобы работать эффективно, не тратить кучу времени на пересылку емейлов туда-сюда и иметь безопасный доступ к данным, ведь большая часть из них — еще и фрилансеры (переводчики, корректоры и т.п.). А еще хорошо бы знать, чем они там занимаются.
Для компании делается веб приложение. AWS бэкенд для него, при порядка 100 сотрудников в системе, обходится в 200$ в месяц, из них большинство уходит на базу данных. Ключевой для Вас момент — вычисления в Lambda на javascript — забирают 15$. Фронт энд запускается на любом обычном компьютере в браузере — это все что волнует компанию об его эффективности.
Разумеется, в такой ситуации самое дорогое для компании — это зарплата разработчика и скорость разработки. Поэтому на С++ такое никто не делает (хотя вроде ничего не мешало сделать в Lambda поддержку С++, это же чистые вычисления! Но нет же — с удивлением обнаруживаем там только Java, Go, PowerShell, Node.js, C#, Python и Ruby).
Ну еще бы, ведь к многопоточности это не имеет абсолютно никакого отношения. Расскажите мне, пожалуйста, как с помощью async/await распараллелить вычислительную задачу.
Вроде специально многопоточность в кавычки взял, нет, не помогло. Да, физически это к многопоточности не имеет ни малейшего отношения. А как часто Вам нужна именно физическая многопоточность? Чаще всего нужна многопоточность логическая — вот сейчас мне нужно делать А и Б одновременно, и чтобы ни одно из них не зависило от другого. async/await — это оно и есть. А вот как раз вычислительная задача с точки зрения конечного пользователя — это что-то неделимое, логически ему нужен просто конечный результат.
KanuTaH
02.10.2019 10:13+3.Для компании делается веб приложение
Веб-приложениями мир не ограничивается. У вас, так сказать, та же болезнь, что и раньше, только наоборот — раньше вы считали, что на C++ нужно писать все, теперь вы считаете, что на нем не нужно писать ничего :) Вас просто кидает из крайности в крайность.
.Вроде специально многопоточность в кавычки взял, нет, не помогло.
Потому что async/await относятся к асинхронному выполнению, а не к многопоточности. Употребляйте термины правильно.
.А как часто Вам нужна именно физическая многопоточности?
Регулярно. Я-то не веб-приложения пишу. Каждой задаче — свой инструмент.arseniy_artmind
02.10.2019 14:03+1раньше вы считали, что на C++ нужно писать все, теперь вы считаете, что на нем не нужно писать ничего
Где я такое писал?
Я написал, что лично я постараюсь к С++ больше никогда не возвращаться. Как и к embedded. Хотя это мои личные пристрастия, я все равно подробно написал, почему для меня это так. Я совершенно четко понимаю, что в мире миллионы С++ разработчиков, триллионы legacy кода на С++, и ни сегодня ни завтра это никуда не денется. Так же как кучи процессоров и RTOS систем, для которых есть только С библиотеки, кучи графических и игровых движков и т.п. Но я считаю, что это потому, что так исторически сложилось, а не потому, что С++ лучше альтернатив. Если бы сейчас я выбирал язык под тот же круг задач, что я выполнял раньше (разработка управляющих программ для научных лазеров, например), я бы всеми силами постарался избежать использования С++, если это от меня зависит, и учил бы Rust. например.
Что в своем оригинальном сообщении я считаю реальностью, общей для всех — это полная ущербность стандартной библиотеки, которая сильно испортила общее направление развития языка. Я просто в принципе не вижу задач, для которых ее можно использовать (ну, разумеется, кроме поддержки legacy, где она уже используется). Если у вас есть нет сильного ограничения по ресурсам, и важно время разработки — Qt и подобное гораздо лучше. Если есть ограничения по ресурсам (например, embedded), то ее опять нельзя использовать, потому что исключения — это непозволительная роскошь. В итоге тысячи проектов, где люди пишут с нуля свои собственные контейнеры, функциональщину и прочее.KanuTaH
02.10.2019 14:29Позиции Qt как раз в embedded и сильны (в числе прочих). Он и на bare metal работает:
www.qt.io/qt-for-mcu
Как говорится, stop believing you should use the standard library for everything. Ей есть альтернативы, и слава богу, что C++ позволяет при необходимости «ужиматься» и не использовать тот функционал, который не нужен. Попробуйте в том же C# (раз уж статья о нем) обойтись без исключений или сборщика мусора — там это вообще не вариант, все это намертво вшито в язык так, что не отодрать даже с мясом. В C++ это решается просто заменой std на более подходящую для данного случая библиотеку и сборкой с -fno-exceptions.
arseniy_artmind
02.10.2019 14:18C++ — это как большая качественная головоломка. Людям с аналитическим складом с ней очень интересно. Но чтобы решить конкретную задачу, нужен эргономичный инструмент, а не головоломка. Если мне нужно строку разбить на подстроки, используя символ или строку как разделитель (что ну очень попсовая задача), я хочу написать str.split(delimiter), это абсолютно естественно. Но почему-то в С++ это не так. Достаточно вбить в гугл how to split a string in C++, чтобы осознать насколько далеко это не так. И мне совершенно непонятно, почему это не так. И на мой взгляд, этому нет никаких оправданий.
KanuTaH
02.10.2019 14:25В Qt, который я главным образом и использую, это делается как раз естественно, через QString::split(), которых там куча вариантов на все случаи жизни :) В std — да, с конкретно этой операцией все печально. Но Qt — это тоже C++ :)
PyerK
02.10.2019 16:35Сплит элементарно делается через std::find, я чуть ниже привёл пример. Вместо функтора можно использовать outiterator, будет похоже на Qt, но теряется гибкость и производительность в некоторых сценариях где создание временной строки не требуется.
KanuTaH
02.10.2019 16:51+1Вот примерно такое велосипедописание arseniy_artmind и называет «люди пишут с нуля свои собственные...» whatever :) Люди либо везде таскают за собой собственную библиотечку из подобных «универсальных» велосипедов разной степени качества, либо просто занимаются переносом их из проекта в проект, и хорошо еще, если с помощью великой технологии copy&paste. Чем меньше тривиального кода типа этого нужно писать, тем меньше вероятность в нем ошибиться и тем лучше для всех.
PyerK
02.10.2019 16:24-2я хочу написать str.split(delimiter), это абсолютно естественно.
Наблюдая за своими учениками, я в принципе понял почему C++ не любят те кто имеет опыт с других языков.
Типичный программист нажимая точечку в своей IDE ожидает выпадающего списка того, что можно сделать со строкой.
Что же он видит в С++? А ровным счетом ничего, со строкой ничего нельзя сделать, с вектором, листом… только положить элемент да и достать. Ни сплита, ни ввода вывода, ни поиска, ни конвертаций, ничего. Тут он делает умозаключение что библиотека в С++ нефункциональная и переключается на другой язык.
Но в С++ алгоритмы и контейнеры не связаны. В любой алгоритм можно подставить любую сущность, и мы имеем комбинаторный взрыв того, что мы можем сделать.
Например идиоматическая реализация split которой я учу:
template <typename Iter, typename Sep, typename F > void split( Iter first, Iter last, const Sep& t, F f ) { while ( true ) { auto found = std::find( first, last, t ); f( first,found ); if ( found == end ) break; first=++found; } }
Хороший студент её пишет без гугла за 5 минут, надо знать только что существует группа алгоритмов std::find. И в результате имеем функцию которая может посплитить что угодно что имеет итераторы (строки\контейнеры\стримы\корутины), а в качестве разделителя может быть как один элемент так и группа. А так как она принимает лямбду, то мы никак не ограничены тем, куда и как сериализовывать кусочки, а так же не создаём тысячи мелки объектов на куче. При небольшом (5%) изменении этой функции, мы можем получить вариант который будет векторизироваться или распараллеливаться. Или же можем получить сплит, работающий на этапе компиляции.
Всего лишь одна функция, но она показывает поистине впечатляющие возможности. 8 строк кода благодаря которым можно расплитить что угодно, и почти как угодно, и мы никак не ограничены типом результата. Поэтому мало знать С++, нужно понимать идеи которые стоят за этим языком.arseniy_artmind
02.10.2019 18:01Я ничего не имею против того, чтобы у студентов развивать абстрактное мышление, это хорошо.
Но давайте представим, как Вашу замечательную универсальную шаблонную функцию использовать на практике.
Немного утрируя, но допустим, пришел к Вам заказчик и говорит:
— А чем это, батенька, ты занимался неделю?
— (Гордо) Создал универсальную функцию разбивания всего на все с минимум оверхэда
— ?
— Ну в стандартной библиотеке нет такой функции. Кстати, вызывать ее достаточно легко: split(str.begin(), str.end(), sep, [&]([не прошло цензуру]) { [не прошло цензуру] })
— ***, мне нужно было разделить «Вася Пупкин» на имя и фамилию, чем ты занимался?!
technic93
02.10.2019 18:06+1Но ведь сейчас split() в многих языках
1) умеют не только строки а также другие контейнеры
2) и возвращают они итераторы
Т.е. на подобии ranges только ещё и в IDE методы выпадают.
DistortNeo
02.10.2019 20:37+1Но в С++ алгоритмы и контейнеры не связаны. В любой алгоритм можно подставить любую сущность, и мы имеем комбинаторный взрыв того, что мы можем сделать.
Равно как и во всех других языках, имеющих шаблоны/дженерики. Просто в C++ это делается крайне неудобным образом из-за неудачного решения по представлению контейнера (вместо собственно контейнера передаются два итератора) и отсутствия методов-расширений (невозможен chaining).
А предложенный вами
split
плох тем, что содержит в себе сразу две функциональности: разделяет коллекцию и выполняет над ней действие f. К тому же, он императивен и требует написания кучи кода вокруг него. А ещё непонятно, чем может являться F. Концепт, что ли, добавьте.
Ведь гораздо удобнее видеть в таком виде:
obj.split(arg).for_each(f);
На худой конец:
for_each(split(obj, arg), f);
Fulcrum013
03.10.2019 00:54-2Не надо путать С++ и stl. Не нравится то что предоставляет stl — ничто не мешает сделать свои контейнеры со своими принципами передачи диапазонов. В этом и есть фишка плюсов — в вынесении всего этого хозяйства в библиотечные средства, позволяющие дополнять/заменять их по своему усмотрению.
А вот на шарпе такую манипуляцию произвести будет очень проблемно, если вообще возможно. И как подсказывает опыт древних без плюсов она все равно не обойдется.DistortNeo
03.10.2019 01:47+2Не надо путать С++ и stl. Не нравится то что предоставляет stl — ничто не мешает сделать свои контейнеры со своими принципами передачи диапазонов
Ну да, стандартный аргумент в пользу C++. И вместо того, чтобы сразу приступать к решению задачи, мы сначала потратим кучу времени на велосипедостроительство.
В этом и есть фишка плюсов — в вынесении всего этого хозяйства в библиотечные средства, позволяющие дополнять/заменять их по своему усмотрению.
Ну да. А потом окажется, что в большом проекте каждый модуль зависит от своей библиотеки. И будем видеть мешанину из QString, std::string, char*, std::wstring и т.д.
А вот на шарпе такую манипуляцию произвести будет очень проблемно, если вообще возможно. И как подсказывает опыт древних без плюсов она все равно не обойдется.
На шарпе это попросту не нужно. Зачем?
Fulcrum013
03.10.2019 03:10-2На шарпе это попросту не нужно. Зачем?
Шарп не используют для решения задач где это нужно. Точнее так будет. А нужно это везде что хотя бы чуть серьезнее хеллоувердов магазина виндоуз.Fulcrum013
03.10.2019 03:21-4Ну да. А потом окажется, что в большом проекте каждый модуль зависит от своей библиотеки. И будем видеть мешанину из QString, std::string, char*, std::wstring и т.д.
А нефиг разрабатывать по принципу натянем побольше говна и палок с гитхаба. Это не разработка а вредительство. Тогда и проблем таких не возникает. А типов строк и т.д. в большом проекте будет в любом случае несколько. Потому что где то удобней/оптимальней их иметь с одной внутренней структурой/семантикой где с совсем другой.
И вместо того, чтобы сразу приступать к решению задачи, мы сначала потратим кучу времени на велосипедостроительство.
Нет потратим немного времени на создание сверхвысокоуровневых абстракций значительно ускоряющих разработку.
Ну да, стандартный аргумент в пользу C++.
С++ — универсальный язык в отличии от шарпа. А это означает что пригоден в любых направлениях разработки. И вот что что, а такая с одной стороны простая, а с другой стороны задачезависимая штука как контейнеры и смартпоинтеры для оных разных направлений должны жить по асболютно противоположным реалиям. Сам же лисапет под названием stl предназначена по большому счету для облегчения студентам перехода с явы, которой школьникам в америках моск насилуют поголовно, и больше ни для чего. Хотя бы потому что любая стандартная библиотека может быть годной для мифического «наиболее частого случая» только за счет того что лучшая вообще ни для какого случая, а для многих случаев принципиально не годна.
Узконишевему шарпу, оказавшемуся непригодным даже для создания на нем профессионального средства визуальной разработки даже совместными усилиями двух мировых лидеров в этом вопросе, естественно это ни к чему.
serbod
03.10.2019 11:54+2Есть мнение, что компьютер должен помогать человеку, а не человек компьютеру.
Нет ничего сложного привязать функции к типу, например, по типу первого параметра. Компилятору без разницы, что там — str.split() или split(str), машинный код будет одинаков. А человеку удобнее и понятнее str.split().PyerK
03.10.2019 14:06-2Компилятору без разницы, что там — str.split() или split(str), машинный код будет одинаков. А человеку удобнее и понятнее str.split()
А где проходит граница что помещать в класс, а что не помещать?
Весь STL был основан на принципах SR и DI, ещё до того как эти принципы были сформулированы.
Если поместить в std::string порождающие паттерны как типичный split, то дело на этом не закончится. Будут те кто недоволен отсутсвием членов класса: toLower() toUpper() toUtf() toAnsi() toLatin() readFromFile() bitBlt() getKerningsPairs() regExSearch() find() boyer_moore_find() replace(). А так же будут недовольные тем, что split`а нет во всех остальных контейнерах и писать обобщённый код — стало невозможно.DistortNeo
03.10.2019 14:31В C# для этого были придуманы методы-расширения.
В C++ же предлагался uniform function call, но из-за того, что он приводит к проблемам, связанным с пространством имён, оно так и висит пропозалом.euroUK
03.10.2019 14:51Причем в C# расширения пишут обычно для дженериков, поэтому не нужно городить огород для всех контейнеров.
public static TResult Min<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector);
И внезапно, мы сможем искать минимум для любых типов, которые IQueryableDansoid
04.10.2019 00:09А вы знаете отличие IQueryable от IEnumerable или просто бездумно скопировали дефиницию из стандартной библиотеки? Так вам C++ ников долго придется об стенку до полного прозрения или наоборот?
euroUK
04.10.2019 10:47+1Нет, что вы, не знал. Всегда думал что IQueryable и IEnumerable это одно и тоже. Просто тупые кодерки из Майкрософта ступили и сделали два одинаковых интерфейса.
А тут посмотрел, и вы просто раскрыли мне глаза.
PyerK
03.10.2019 15:22Да, основной мотиваций UFC в с++ Саттер как раз называет автодополнение в IDE (discoverability), о котором я писал.
Но если его примут, все алгоритмы всё еще принимают итератор первым элементом, или executionPolicy. Поэтому, без STL 2.0, выгода сомнительна иначе будет ещё одна тысяча новых перегрузок.
В тоже время концепты потенциально обещают discoverability, тк уже есть какой никакой но критерий для фильтрации аргументов, и увода внимания с UFC на задний план.
Я думаю, UFC имеет шанс только после reflection, тк Саттер все свои маркетинговые силы бросил в этом направлении.
Fulcrum013
03.10.2019 04:42-3Расскажите мне, пожалуйста, как с помощью async/await распараллелить вычислительную задачу.
Никак. Оно предназначено для распараллеливания одной вычислительной задачи и нескольких операций ввода вывода.
Ну еще бы, ведь к многопоточности это не имеет абсолютно никакого отношения.
Имеет и еще какое. Даже если вызывающий async операции код не создает потоки. Операции ввода-вывода обслуживаются потоками ядра, с которыми точно так же необходима синхронизация и т.д. Ну и вообще начните с определения потока. Поток это асинхронный контекст выполнения. Так что любая асинхронность по определению многопоточность, независимо от того как потоки переключаются, какие средства управления потоками имеются в распоряжении, и какие именно задачи выполняет каждый из асинхронных контекстов.
self
02.10.2019 00:10+2Неохота разбирать все по каждой фразе, но вобщем — дискуссия несостоятельна. В том смысле, что у каждого инструмента есть своя ниша, и есть своя устоявшаяся практика. Аргументы насчет быстрого развития C# и медленного C++, это как раз больше аргументы в пользу C++, т.к. быстрое развитие обесценивает знания и опыт, и инструменты постоянно находятся в лучшем случае в руках «экспериментаторов». Т.е. мало кто знает, как лучше, и как надо — а делают так, абы работало. На выработку правильных подходов уходят годы, и когда инструменты меняются, это все идет коту под хвост. Кому нужно такое развитие, если от этого страдает качество?
Ну и пара слов насчет UI — прекрасно он делается и на C++, спасибо Qt. Тем кто скажет, что Qml это не плюсы, я отвечу, что и XAML как бы не C#. И даже UI на основе QWidgets гораздо ближе к XAML, чем WinForms.
А самый фундаментальный недостаток C# — это то, что им по прежнему рулит Microsoft, что бы там ни говорили про .NET Foundation и прочие игры в open source. А Microsoft давно потеряла доверие, вспомним что было с Windows Phone, с Silverlight, с .NET Compact / Micro Framework — где это все? Это корпорация, где шла война кланов, и где победил Azure. Вот и все, что нужно знать про эту (гнилую) контору.
vasiliuz
02.10.2019 09:10+1Опишу свою историю: есть «железный» коммерческий продукт, управляется по юсб. Нужно написать юзер-френдли софт под вин и мак. Сначала выбор пал на C#, были долгие мучения заставить работать его под МакОС с Моно… Возможности Моно в плане GUI очень скудные. Работает очень криво. Баги под маком от OpenDialog'а и дальше… Юзерам объяснить зачем приложению в 30 Мб, скачивать и устанавливать Моно на 1Гб тоже тяжело… То, что в статье пишут про 150Мб — не верно (ну или не совсем верно). Был выбор или Qt или, о, Боже, С++ Builder. Остановились на Билдере… На его фреймворке FMX. Такое ощущение, что делфи там же, где и 20 лет назад, и на тех же костылях. IDE глючная, С++ портирован с Делфи -( компиляторы под вин32, вин64 и мак ос разные, поддерживающие разные стандарты С++. Это всё боль разработчика. Но! Один код под винду и мак. очень гибкие механизмы по работе GUI. Идея FMX оч правильная, но хотелось бы, чтобы ее реализовали в MS, а не в Embarcadero. Я понимаю, что рынок десктопных приложений очень мал уже. И вся ориентация на веб. Но когда пишут, что C# кроссплатформенный, это сильное преувеличение… Может какой-то бек-энд сервер на нем и можно сделать, но с десктопом еще не скоро… Моно жалок. Как по мне, C# очень привлекателен для разработчиков, согласен, но нужна реальная кроссплатформенность в нынешних реалиях. Поэтому и приходится быть на С++ и выбирать между Juce, QT, и FMX от Embarcadero.
euroUK
02.10.2019 09:18Все зависит от сложности UI, может Avalonia на .Net Core вам бы подошла.
И нет, то что выше писали, это не Mono. Выше писали про .Net Core именно. И вы даже можете не ставить отдельно пакет, все можно включить в саму программу (но не надо так делать)Siemargl
02.10.2019 10:50-1Советовать использовать бета-версии в продакшн????
NET Core 3 вышла позавчера, а Авалония до сих пор 0.8Larymar
02.10.2019 10:52-11) бетта снята, почитайте
2) она 8, 9я вот вот готова, а после будет 0.10, что вам дает нумерация?
3) у kekekeks в его статьях достаточно примеров удачных приложенийSiemargl
02.10.2019 10:57-2Я умею читать.
Состоялся очередной бета-релиз AvaloniaUI 0.8.
На гитхабе последний 0.8.2 bugfix releasekekekeks
02.10.2019 11:13+20.8 ретроспективно назначили стабильным релизом, ввиду, как бы это сказать, стабильности и готовности к использованию на десктопах. Уже после публикации на хабре.
Версионирование пока так и будет в стиле 0.123.1 по требованиям SevVer, поскольку бинарной обратной совместимости между версиями в ближайшее время не планируется. Ну или перейдём на браузерную модель версионирования с новым мажорным релизом каждые несколько месяцев.
vasiliuz
02.10.2019 11:58Сейчас, интерфейс приложения, выглядит полностью стилизован: от кнопок, менюшек, списков, ползунков, графиков… И само приятно, что абсолютно одинаково, что под win, что под mac.
exmp.1
exmpl.2
exmpl.3
Моно же был абсолютно сырой, ну от банальных вещей типа мультивыбора файлов в openDialog, прорисовывалось в нем что-то криво. И до проблем с обычными контролами. Вообщем, всё что касалось взаимодействия с юзером вне винды, оставляло ощущения гуляния по минному полю. В одном из продуктов было реализована простенькая утилитка к одному из продуктов, на Моно: там просто пара кнопок и пара listbox… В итоге отказались от саппорта под мак.
Раньше, иногда, фыркали на IDE Visual Studio, но после перехода на Embarcadero — пришло понимание, что MS это просто идеально -) Но идея с их (Embarcadero ) фреймворком FMX очень не плохая (разработчик россиянин Brovin Yaroslav). Жаль, что реализована не в MS, а в Embarcadero. Есть боль при разработке, но для юзеров все гладко. При Моно было наоборот. Я бы с удовольствием вернулся в MS среду, с нормальной кроссплатформенной поддержкой в плане GUI.
Есть еще фреймворки JUCE и Qt. Но там свои приколы. У JUCE лицензии не нравятся…
Fulcrum013
03.10.2019 03:39-4Идея FMX оч правильная, но хотелось бы, чтобы ее реализовали в MS, а не в Embarcadero
Хотелось чтобы ее реализовал Борланд. Но так понимаю идея не сбыточная. А MS в этом плане это направление всухую слил еще в 95-ом. Вплоть до того что куцый обрубок Билдера который называется WinForms делал для MS именно Борланд.
Такое ощущение, что делфи там же, где и 20 лет назад
А куда она может двинуться? Автоматика управления жизненным циклом плюсового разлива как не вписалась в паскалевский синтаксис так сейчас не вписывается. Потому и остается общение с VCL на «С c классами» примерным аналогом которого является паскаль/дельфа а не так как это принято в плюсах. В общем пока дельфу не похоронят окончательно и VCL/FMX не перепишут полностью на плюсах нового взлета там не будет. А с учетом того что в своей нише крупного корпоративного софта, которому свистоперделки не просто не нужны, а принципиально противопоказаны, оно еще в 90-х за счет принципа zero-code, реализованного для систем учета практически на 100%, вытеснило практически все остальное и свои позиции сдавать не собирается, то делать это никто не спешит.
Раньше, иногда, фыркали на IDE Visual Studio
Ну еще бы. Вместе с C# Builder Майкрософту досталась и все борландовское наследие по IDE невизувльной разработки. И развить они его развили норм. По удобству вижак почти ничем не уступает IDE Borland C++ 1.0, и при этом имеет все новшества типа проверки синтаксиса на лету и т.п. Ну хотябы потому что для внутреннего использования у MS вопрос невизуальной разработки api и т.д. основной. А Embarcadero средства работы с кодом не развивало по ходу от слова совсем, потому как основная концепция в основной нише таки zero code и средства редактирования кода носят вспомогательный характер.Раньше, иногда, фыркали на IDE Visual Studio, но после перехода на Embarcadero — пришло понимание, что MS это просто идеально -)
Ну основная претензия к вижаку до 19-го — компилятор крешится просто задолбал. С 19-го багло такое что ужас. Вплоть до вылета экскепшинов при попытке закрытия вкладки с кодом и зависаний при переключении дебаг/релиз. Компилятор как крашился так и крашится. Единственное что догадались добавить вывод сообщения на какой именно строке кода. До этого приходилось код комемнтить построчно чтобы это найти.
Embarcadero себе таких багов в релизе не позволяло никогда. Не говоря уже про Борланд.
Был выбор или Qt или, о, Боже, С++ Builder.
Ну Qt это такая штука которая впитала в себя абсолютно все недостатки как VCL и MFC так и stl, не поимев при этом абсолютно никаких преимуществ.vasiliuz
03.10.2019 13:28Суть статьи С++ vc C#… Я просто поднял вопрос реальной кроссплатформенности в рамках десктопных приложений. С# на данный момент не имеет нормального решения для создания таких приложений: все или в вечной бете, или в очень сыром состоянии, или под виндовс. С++ имеет больше вариантов реализаций. С# приятней для разработчика. На мой взгляд, у C# на первом месте забота о комфортности разработчика, а на втором месте результат работы разработчика. Еще момент, С# полностью декомпилируется — по сути, весь ваш код это opensource. Многих это не устраивает. С++ тоже декомпилится, но до «готового» кода пилить и пилить.
С/С++ это дефакто стандарт для embedded. И лучшей альтернативы нет. ИМНО и не нужно -) Потому, что там где вы работаете с железом вы, скорее всего не будете писать int, а будете писать UInt32 или Int32, если хотите контролировать происходящее.euroUK
03.10.2019 15:05Потому, что там где вы работаете с железом вы, скорее всего не будете писать int, а будете писать UInt32 или Int32, если хотите контролировать происходящее.
То есть, как будто в C# нет UInt32, а int в C# означает что угодно, а не Int32.
А вот я такой иду смотреть C++, хочу научиться, и вижу в официальном референсе
int32_t
int_fast32_t
int_least32_t
И я такой, WTF?vasiliuz
03.10.2019 15:33Вы вытащили это с контекста… Речь шла о embedded. И там преимущественно, даже не С++, а С99. И про int переживают с самой статье, а не я. Я сделал упоминание, в рамках того, что там, где нужно, переменные, нужного типа, применяются вполне осознанно.
Безспорно, существует много легаси кода. И есть проблемы с ним. Но стоит ли винить С/С++ за то, что он был основным языком, и практически все с чем и на чем мы работает было написано на нем. Язык продолжает развиваться, и да, легаси его ограничивает. Стоит ли это упрека? Да, порог вхождения в С/С++ выше, чем в С#.
C/C++ это более низкоуровневые языки, C# более высокоуровневый. С++ обвешанный фреймворками — может то что и С#. С# не может «залезть глубже» по своей сути…
self
03.10.2019 15:27-1На C# вполне можно пилить автоматизацию под железо, особенно если это железо подключено через последовательный порт :) И это будет вполне себе embedded, по определению. Четырех-ядерного Intel Core на это вполне хватает)
vasiliuz
03.10.2019 15:43Управление по протоколу можно писать на чем хочешь… Особенно если это UART. Это не тот embed, о котором я говорю. Embedded это когда вы управляете процессами в реальном времени, когда вы считаете операции за такт процессора, когда вы экономите память, когда математика подводится под архитектуру, когда вы реально можете видеть, чем inline отличается от обычной ф-ции. и т.д.
self
03.10.2019 16:17Ну так и автоматизация через UART, тоже вполне себе происходит в реальном времени. Например дозатор чего-нибудь — получаем параметр, смотрим уже хватит или еще подождать, когда хватит посылаем команду железу что-то выполнить. При этом можно отправлять данные куда-то на сервер, и показывать красиво в UI. И такое ПО, по определению, тоже будет являться встраиваемым. Требования к нему просто, менее жесткие. Особенно если железо — штучный товар. Я уже молчу про софт для банкоматов и кассовых терминалов — там C# аж бегом можно применять.
vasiliuz
03.10.2019 16:43+1"… посылаем команду железу что-то выполнить..." Вот железо, которое будет что-то реально выполнять- это и есть уровень С/С++. А послать команду этому железу что-то выполнить можно и на HTML.
И если эту команду захочется послать не с консоли, а с ГУЯ, и не только с винды, то С# и тут не оч подходит — С# вин ориентирован, вся его кроссплатформенность сводится к «консольному»/серверному back-end«у. В лучшем случае, сейчас, его хватит на легкий конфигуратор — галочки расставить. Но для этого есть 1001 альтернативный способ… Плюс, повторюсь, его код полностью открыт. Это все-равно, что управлять банкоматом на каком-то bat»нике.
C# приятен в работе, все за тебя написано, удобно… Но и плата за это соответствующая.self
03.10.2019 17:03-1Да нормально C# подходит. Железо готовое — модули от ICP-DAS, управляются командами по RS-485. На C# пишется логика всего процесса. И т.к. это специальное ПО под специальный комп, на котором больше не будет (не должно) ничего работать, то вполне можно поставить туда любую винду и наваять хоть на C# 2.0 нормальное приложение, которое легко дебажить и поддерживать. И которое будет работать годами (при соответствующей настройке винды). Я этим как бы занимался, несколько лет.
vasiliuz
03.10.2019 17:35-1Я этим как-бы занимался тоже… Сименсовые контроллеры… точно так же управляются по RS485… Вся производственная линия, и очистные сооружения управляются софтом написанным на С#. Такая связка почти производственный стандарт сейчас — дешево и сердито, низкий порог вовлечения сторонних программеров, которым дается более-менее адекватное ТЗ, и они не понимая сути, делают просто удаленное управление по сценариям, со сбором статистики. Но если, поставить задачу сделать тоже самое нод линукс\мак\винду. И чтобы вашим софтом пользовалось более 5 обученных человек… Чтобы софт выглядел дружественно, симпатично и одинаково под всеми ОС. Чтобы у вас был один код на все ОС. То С# вам не помощник… Что-то, как-то, и через /*№" может и создадите. Но это будет костыль на костыле. Поэтому я тут не сказки теоретизирую…
self
03.10.2019 18:03Ну так о чем мы спорим тогда. Если добавляются требования Мак, Линукс, установка на пользовательские компы, то это уже не embedded тогда, и выбор инструмента должен учитывать эти требования. И в таком случае, очевидный (для меня) выбор инструмента — Qt. Я даже больше скажу — если бы Qt в том виде как он есть сейчас, появился на 15 лет раньше, то и C# мог бы умереть, не родившись.
vasiliuz
03.10.2019 18:20Я вообще не спорю… Это просто мое мнение из моего скромного опыта. Просто по статье получается. С++ весь такой отживший, сложный, медленно развивающийся, бюрократичный. А C# весь такой современный, передовой, кроссплатформенный, удобный. ИМНО истина где-то посередине… Плюс повторюсь — можно смело считать, что С# приложение поставляется с исходным кодом сразу… Кому-то (мне) это не нравится, кто-то от этого в восторге…
Fulcrum013
03.10.2019 23:41-1которым дается более-менее адекватное ТЗ, и они не понимая сути, делают просто удаленное управление по сценариям, со сбором статистики.
Это диверсия называется
дешево и сердито, низкий порог вовлечения сторонних программеров,
Ндя. В америках конторы которые автоматизацией и прочим хайтечем занимаются выпускников вузов раскупают еще на последнем курсе. И з/п дают на время стажировки такую «от» что в энтерпрайзе это глобально «до» а в гугле 2/3 этого глобально «до». Догадаетесь почему?
А тут типа порог вхождения стипа нижают. А потом сказки рассказывают на всех углах что типа пожары в пожары в торговых центрах и т.д. де агенты ФБР устраивают.vasiliuz
04.10.2019 00:03+1Я обсуждал вполне нишевый сегмент… Как это обычно происходит у нас (не америка): есть инженер-программист, который программирует промышленные контроллеры (те же сименсы и т.п) он по сути главный, всю логику, автоматику он реализует «железно»… Далее привлекается программист, который пишет приложение, которое отображает, как правило, визуально состояние системы, ведет и сохраняет логи, в самом крайнем случае обеспечивает сценарную логику. Если возникает некая ошибка — сигнализирует оператору. По сути все приложение — это парсер с таймером. Студенты последних курсов — как раз очень подходят: дешево и сердито… С# для таких задач — просто идеальное решение. Все сливки получает инженер — рутину за немного денег делает программист. Все счастливы, все заняты. Инженер со своим С++, и программист с С# -)) Така я вот диверсия -)))
Fulcrum013
04.10.2019 00:19-1Если возникает некая ошибка — сигнализирует оператору.
Если бы не вот это это было бы вполне допустимо.
А так это диверсия чистой воды.
Fulcrum013
04.10.2019 07:32-2Я обсуждал вполне нишевый сегмент… Как это обычно происходит у нас (не америка):
Да хоть Африка. Главная причина всех багов, в том числе таких которые приводят к серьезным авариям — недопонимане задачи. И никакие средства разработки эту болезнь не лечат в принципе. Только досканальное исследование предметной области и анализ задачи. Т.е. сам подход с использованием студентов вслепую — это еще гораздо большая диверсия чем шарп туда пихать.
mayorovp
03.10.2019 17:29"Реальное время" и "сборщик мусора" — несовместимые понятия.
Точно так же несовместимы "реальное время" и "ОС общего назначения".
vasiliuz
03.10.2019 17:40именно это я и имел ввиду, когда писал, что С/С++ сможет, а C# по своей природе не способен, на определенные вещи.
self
03.10.2019 18:11Реальное время, скажем так, может иметь разную степень «реальности». А процессы, которыми управляет ПО на C#, могут иметь определенную цикличность. Тогда в удобные моменты, достаточно просто вручную запускать сборку мусора, что с достаточно высокой надежностью гарантирует от возникновения проблем на критичных участках. Плюс, дополнительно можно отслеживать метрики по управляемым ресурсам (например памяти) и заранее принимать меры при достижении опасных уровней. Но обычно, на C# пишут то, что такого контроля не требует, а (теоритически возможные) задержки в 10-20 мс на процесс особо не повлияют. По шине RS-485 скажем, интервал опроса обычно десятки миллисекунд, за это время GC успеет 100 раз отработать.
Siemargl
03.10.2019 20:19+3Реальное время, скажем так, может иметь разную степень «реальности».
это просто необразованность. нет понимания основ
ну или так сказать, имеет некоторую «степень образованности» =)
Подсказка. «Реальное время» не связано с быстродействием.self
03.10.2019 20:57-1Да знаю я, с чем оно связано. Хорошо настроенная WinXP без всяких излишеств, не предподносит никаких сюрпризов по времени реакции. Там где тех.процесс допускает задержки до десятков мс, нет никаких причин не применять десктопные решения вроде Windows и C#, для создания встраиваемого ПО. Вас кстати не смущает, что MS выпускала и до сих пор выпускает специальные редакции Windows, называемые Embedded? Все отличие которых от десктопных, составляет 15 лет гарантированной поддержки и чуть ли не пофайловая конфигурация образа. И Embedded на самом деле, это не про размер, а про назначение, ПО и системы.
Fulcrum013
03.10.2019 23:27+1нет никаких причин не применять десктопные решения вроде Windows и C#, для создания встраиваемого ПО.
Как это нет? А как же предупреждение Майкрософта о том что не предназначено для управления оборудованием в реальном времени? Или лицензионное соглашение оно там так чтоб галочку нажать?
Ну и еще такой вопрос — а если оно взорвется или задавит вы в курсе что и тот кто такое решение принял и тот кто его на работу нанял будут лес валить очень долго.Kanut
03.10.2019 23:37А можно ссылку на лицензию которую вы имеете ввиду и цитату конкретно этого места? А то что-то не могу в актуальной embedded лицензии такого найти.
Fulcrum013
04.10.2019 00:31А можно ссылку на лицензию которую вы имеете ввиду и цитату конкретно этого места?
Да пожалуйста:
16. RESTRICTED USE. The Microsoft software was designed for systems that do not require fail-safe performance. You may not use the Microsoft software in any device or system in which a malfunction of the software would result in foreseeable risk of injury or death to any person. This includes operation of nuclear facilities, aircraft navigation or communication systems and air traffic control.
Хотя по большому счету достаточно отсутствия всякого присутсвия сертификата на применение в системах реального времени.Kanut
04.10.2019 08:07+2Здесь нет ни слова про системы реального времени. Только про отказоустойчивые. А это совсем разные вещи.
Fulcrum013
04.10.2019 09:59-1В системе реального времени — не вложилась в лимит времени это отказ системы.
mayorovp
04.10.2019 10:25Но не всегда отказ системы — это что-то страшное. Например, запись компакт-дисков — тоже как бы задача реального времени. Но цена отказа тут — всего лишь запоротая болванка (и то если у нас не RW-диск).
Fulcrum013
04.10.2019 11:01-1Но не всегда отказ системы — это что-то страшное
You may not use the Microsoft software in any device or system in which a malfunction of the software would result in foreseeable risk of injury or death to any person.
В любой системе промавтоматики управляющей оборудованием такой риск всегда есть. А написанно именно так потому что существуют системы и не реалтаймовые и не управляющие оборудованием где такой риск тоже всегда есть.mayorovp
04.10.2019 11:58В любой системе промавтоматики управляющей оборудованием такой риск всегда есть.
Насколько я знаю, в промавтоматике приняты аппаратные цепи безопасности (там, где это возможно). При выходе из строя управляющего компьютера оборудование просто останавливается.
Да, это убытки. Но риска для здоровья нет.
Kanut
04.10.2019 10:50+2У вас дыра в логике. Не каждая система реального времени должна быть отказоустойчивой. И не каждая отказоустойчивая система должна бытъ системой реального времени.
Fulcrum013
04.10.2019 11:09У вас дыра в логике.
То у вас дыра в логике. Потому что реалтамовость — одно из требований по отказоустойчивости к системе по своей сути. Т.е. недопустимость отсутсвия реакции в заданный лимит времени.Kanut
04.10.2019 11:24Потому что реалтамовость — одно из требований по отказоустойчивости к системе по своей сути.
С каких это пор?
У меня может быть например отказоустойчивая система, вся задача которой это сохранять логи событий. При этом она совсем не обязательно должна делать это в реальном времени и вполне достаточно если все логи будут просто сохранены на момент выключения системы.
Fulcrum013
04.10.2019 11:35-1У меня может быть например отказоустойчивая система, вся задача которой это сохранять логи событий
А какие у вас в другой системе требования по устойчивости к отказам никакого отношения не имеет к требованиям отказоустойчивости в системах управления оборудованием.
Fulcrum013
04.10.2019 11:46и вполне достаточно если все логи будут просто сохранены на момент выключения системы.
The Microsoft software was designed for systems that do not require fail-safe performance
Т.е. нет абсолютно никакой гарантии что система обеспечит сохранение ваших логов. К примеру банально не закрешится на самом интересном месте.Kanut
04.10.2019 11:54И что? Вы вообще понимаете что вы уже пошли по второму кругу? Никто не спорит что Microsoft embedded не годится для отказоустойчивых вещей. Но отказоустойчивые системы это не тоже самое что системы реального времени.
И есть системы реального времени, которые не должны быть отказоустойчивыми. А вы утверждали что Microsoft embedded не годится именно для систем реального времени. Где вы это вычитали?
self
04.10.2019 02:24Майкрософт и так ни за что не несет ответственности, так что их предупреждения до одного места. А насчет взорвется или задавит, это ваши собственные фантазии. Требования определяют инструмент, и с этим никто не спорит. Требования просто разные бывают, как и сумма, которую за это готовы заплатить.
Fulcrum013
04.10.2019 05:12Майкрософт и так ни за что не несет ответственности, так что их предупреждения до одного места
там прямо написано: вам не разрешается использова програмное обеспечение Майкрасофт в устройстве или системе чей отказ может привести к ранению или смерти людей. Включая ядерные установки, навигацию самолетов, системы связи, управление воздушным движением.
То что то не перечислено не означает что оно разрешено.
Fulcrum013
04.10.2019 05:17Требования просто разные бывают, как и сумма, которую за это готовы заплатить
В для начала в законах и нормативных актах проконсультируйтесь. А то у нас на заводах не то что системы индикации сбоев, компы которые за калибрацией весов наблюдают на сертифицированных к реалтайму осях. Потому что подсудное дело в систему промышленной автоматизации несертефецированный софт пихать или неквалифицированных спецов не то что в разработке, даже в техническом обслуживании задействовать.
Да и не путайте FA и Embedded когда будете нормативные акты смотреть. Это две огромные разницы.
В FA могут начальника отдела лет на 5 упечь к примеру за то что некоторый тип датчика смещен на пол метра. это при том что длина линии автоматизации 250 метров и никакой аварии не было.
А Embedded в лампочке фазы коммутирует. Или в микроволновке светодиодиками моргает. Хотя конечно и не только это делает. Но его смысл девайс встроенный в устройство и выполняющий в большинстве случае преимущественно информационные задачи а не задачи управления.
Fulcrum013
04.10.2019 01:02Там где тех.процесс допускает задержки до десятков мс, нет никаких причин не применять десктопные решения вроде Windows и C#, для создания встраиваемого ПО.
Знаете я вот в свое время на одном прокатном стане работал. Так там в системе самый маленький лимит времени отработки был 50мс. И вы туда винду с шарпом хотите поставить? Вы когда нибудь видели как 100-тонный валок перебитый пополам летит по линии прокатки?
А полетит ежедневно. Потому что кроме времени отклика важен еще приоритет обработки сигналов а винде они в кучу свалены вместо обработчиков прерываний заглушки которые сваливают было прерывание в очередь без приоритетов и когда оно там отработает и в каком порядке вообще неизвестно. Немчура кстати предлагала на винде решение. Только со своим кернелом который это обеспечивает. Этот настолько реалтаймовый что часть тамогавков на нем летала. И стоил он 50 килобаксов копия. Только вот крайняя версия для которой его делали была хрюшка. А дальше сказали все не можем. Догадайтесь причина какая? Банально в ней .NET из коробки присутсвует. Все непригодна. Наверное там в Сименсе вооще дураки работают по вашему?self
04.10.2019 02:56Дотнет из коробки, прямо вот сразу готовый к использованию, появился ЕМНИП только в Win8. И это всегда была проблема дотнета, отсутствие его рантайма у большинства юзеров. Винда, а именно WinXP, если правильно сконфигурирована, вполне надежная и предсказуемая система (в частности, если отключено все лишнее и не абсолютно необходимое, в т.ч. сеть, звук, проводник и т.д.). Простые вещи на ней можно делать (напимер дозатор песка или цемента). Тот кейс, что вы приводите, требует многоуровневой распределенной системы управления, и на каждом уровне будут свои решения (начиная с датчиков и автоматики на уровне железа, до контроллеров сбора данных и операторских пультов, заканчивая SCADA системой которая все это объединяет). Понятно что одним компом с виндой и поделкой на шарпе тут не обойтись.
Fulcrum013
04.10.2019 04:38Простые вещи на ней можно делать (напимер дозатор песка или цемента).
Майкрасофт так не считает.
Тот кейс, что вы приводите, требует многоуровневой распределенной системы управления,
Реально там хватает двух УВМ с 800Khz тактовой и 768Кб тактовой каждый производства конца 70-х. Да и форточки местные тоже тянут. Терминалы операторов и графические мониторы отображающие схему. А винду туда пускать нелязя без замены кернела железо какой бы мощности ни было.
Fulcrum013
04.10.2019 05:38По шине RS-485 скажем, интервал опроса обычно десятки миллисекунд, за это время GC успеет 100 раз отработать.
Я вот не далее года назад наблюдал картинку маслом. Там конечно не с автоматикой слава богу связано было. А с сервами которые друг друга тестировали раз в 6 часов. И при этом тесте лимит времени на счет тестовых данных и отклик был 2 секунды. И все норм укладываются там в милисикунды. месяц-два — начинают ложится. Верне не ложится а не проходить тест. Что оказалось под счет тест нужен был непрерывный буфер не очень большой метров десять. И вот как раз по приходу задачи он начинал GC-шить по всей видимости свап потому что занимало это от 20 до 45 секунд. Конечно линукс и ява это как бы не винда и шарп. Но как бы не стоит надеяться на то что GC управится в какой то лимит времени. Этот лимит может оказаться непредсказуемо и абсолютно неожиданно гораздо гораздо больше.
Fulcrum013
04.10.2019 10:30Плюс, дополнительно можно отслеживать метрики по управляемым ресурсам (например памяти) и заранее принимать меры при достижении опасных уровней.
Есть только один способ гарантировать наличие нужной памяти — иметь ее распределенной на старте системы.
self
03.10.2019 15:29+1Ну Qt это такая штука которая впитала в себя абсолютно все недостатки как VCL и MFC так и stl, не поимев при этом абсолютно никаких преимуществ.
Оборжаться просто))) Интересно, за что же его все любят? И где были бы плюсы сейчас, если бы не Qt?Fulcrum013
04.10.2019 04:43Оборжаться просто))) Интересно, за что же его все любят?
А все это кто?
И где были бы плюсы сейчас, если бы не Qt?
Ну живут же крупные конторы без Qt. Сименс к примеру или Дассо. И еще куча мировых лидеров по производству софта. Вы ее вообще где то в том что не раздается бесплатно с гитхаба видели?Chaos_Optima
04.10.2019 10:50Практически весь совт для комп графики написан на Qt (maya, katana, nuke, hudini и тд) даже в стандартах VFX прописано какую Qt нужно брать vfxplatform.com
seslomayer
Достаточно спорно, вернее это совсем не так. Подобные утверждения создают путаницу и только вредят C++, да и объективности как таковой. Правильно говорить, что на C++ ты можешь написать код, который быстро работает. А вот на дотнете не всегда. Дизайн языка/язык в общем виде, как и уровень его пользователей, определяют тот набор возможностей(и от языка, который даёт возможности. И от программиста, который хочет и может использовать). И уже это вкупе даёт ту самую производительность.
Если программист не знает как пользоваться возможностями, либо знает, а язык не позволяет — ничего не получится. И C++(современный) хоть и даёт практически безграничные возможности(относительно, конечно), но первую часть тезиса никто не отменял.
И это чистая правда. Причём это сложно донести не только людям со стороны, но и множеству программистов на самом C++.
pvsur
мда… утверждать что Шарп лучше потому что на нём мордочки можно быстрее рисовать чем на тролтеховской куте и они красивее получаются… я в 2005-2010 гг. рисовал в борландовском билдере такие, что и сейчас не всегда получаются. с ворованными девелоперекспрессовскими компонентами, с наборами джедивцл, фастрепортом это было просто, быстро и красиво. но как можно приравнивать мордочки и качество языка?
KanuTaH
Ну, честно говоря, если уж писать "наскоро" GUI на Qt, то я бы стал писать его на Qt Quick, а не на плюсовых виджетах, а к этому GUI на Qt Quick уже подключать какую-то "рабочую" логику уже на плюсах, благо делается это элементарно. У меня был небольшой опыт написания гуя и на C# (WPF+XAML), и мне Qt Quick понравился больше.
mrbaranovskyi
Ну, спорное заявление..)) Ооочень спорное.
KanuTaH
Ну, я про себя пишу. Для меня, например, вопрос возможности переиспользования одного и того же кода и на десктопе и на мобилках довольно важен. Qt мне такую возможность в значительной степени обеспечивает и на Windows, и на Linux с MacOS, и на почившем в бозе Windows Phone, и на Android с iOS. WPF — это только платформы MS, ну по крайней мере в свое время так было, может, сейчас с этим получше, но в одном из соседних обсуждений мне говорили, что лучше с этим не стало.
Kanut
Какой-нибудь Xamarin для вас тоже не вариант?
P.S.Ну и по хорошему надо будет посмотреть что в плане кроссплатформа нам реально сможет дать .Net 5.0
KanuTaH
Ну голый Xamarin, насколько я помню, это просто обёртка из классов поверх возможностей целевой платформы, то есть, условно, для Android будет один код, для iOS — другой. Xamarin Forms вроде как облегчает этот вопрос, но… только для Android, iOS и UWP, насколько я понимаю. Linux с MacOS в пролёте.
Kanut
Ну если вы вот прямо под все ОС пишите, то тогда C# действительно менее удобен. Как минимум на данный момент уж точно.
Luminisc
Если говорить о кроссплатформенности, то корректно говорить о .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), при этом в моих руках всё удобство и гибкость С# и тд.
Siemargl
Практически все платформы, это полторы? ))))
KanuTaH
Мне как бы не особо интересно «написание библиотек», мне интересна такая разработка продукта, в процессе которой я мог бы переиспользовать как можно больше ВСЕГО кода продукта, в том числе UI (в идеале 100%) при переводе его с платформы на платформу. Авалонию я не пробовал, но вот здесь мне писали, что она очень сырая, да и поддержка мобильных платформ там, насколько я вижу, числится как экспериментальная.
Luminisc
Простите, а куда вы собственно пишете всю бизнес-логику без библиотек? Прям в 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. Есть ещё какие-то варианты?
KanuTaH
Ну вот я ниже в качестве примера привел ссылку на продукт, который сейчас написан на C++ и Qt, и доступен под Windows, Linux, MacOS, под которые он собирается ну практически со 100% переиспользованием кодовой базы, ну и плюс имеет «облегченный» вариант для мобилок (Android, iOS) на тех же технологиях, которые тоже шарят между собой кодовую базу. Возможно, конечно, это у вас пойдет по графе «high performance calculations» (а их там есть, это да).
Luminisc
Интересный продукт, мы чем-то похожим в университете занимались, с моделями сердца работали и ещё какими-то органами (их срезы и модели в виде облаков точек).
Касательно тех критериев что вы описали в том комментарии, я считаю что это можно сделать на C#, и общую кодовую базу (.NET Standard), и UI хоть под десктоп и под мобилки (AvaloniUI + XamarinForms), при этом ни на шаг не уходя от C#.
Тут я вижу только 2 подводных камня:
1. HPC — а для предложенного вами приложения это, я считаю, самый критичный момент
2. Движок для рендера
Насчёт первого, я думаю бОльшую часть можно покрыть с использованием ILGPU (буквально веткой ниже пару слов написал об этом). Не думаю что можно абсолютно всё покрыть, всё таки в шарпе ещё не всё радужно с векторизацией как хотелось бы.
Для второй проблемы, есть два варианта. Это использование OpenGL(OpenTK) или любой другой плюсовой библиотеки для рендеринга, ну или честный .NET вариант (таких примеров правда не видел). То бишь данный момент нас так или иначе тянет к решениям на плюсах.
Либо, использование Unity3D в качестве UI. При этом данный вариант решает проблему как UI кроссплатформенности вообще (один 'UI' под все платформы), так и вычислений (используя Compute Shaders, который тоже в итоге кроссплатформенный и кроссжелезный).
Но боюсь что Unity не подходит для «кровавого enterprise'а», хотя если сильно захотеть…
Звучит такое решение конечно самоуверенно, да и я не знаю какие в вашем продукте есть подводные камни, какая архитектура и тд. Но если отвечать на вопрос что можно ли такое сделать на C#, я придерживаюсь мнения что да, это возможно.
KanuTaH
Про ILGPU я прочел, да. Но, насколько я вижу, это CUDA only, а значит, только NVIDIA. Там, вроде, стоит красная галочка напротив AMD, но красная — это значит «когда-то в будущем». Ну и там не только и не столько рендеринг, сколько именно реально тяжелые вычисления при всяких там автоматических сегментациях, например, для чего и нужны собственно CUDA и OpenCL, а также при отсутствии нужных карточек это должно делаться и на CPU, причем как можно более эффективно. Не знаю, как у C# с этим. И насколько там будут эффективны compute shaders у unity — тоже вопрос. Ну ОК.
mrbaranovskyi
«А вот на дотнете не всегда.»
— и как выглядит это «не всегда», мне интересно?
У нас есть свой 3Д рендер, куча математики, процессинг высокополигональной геометрии и всё, таки, быстро работает. У мелко-мягких bing. Единственное где возникают проблемы это c gpu. Тут без плюсов пока сложно, а гибридайзером (или чем-то подобным) пользоваться не особо хочется.
А вообще, это глупый спор… всегда использовались параллельно и никто не страдал…
Luminisc
К слову о GPU на С# и необходимость в С++. Есть такая здоровская библиотека для .NET Core, называется ILGPU. Она позволяет писать код, прям на С#, который потом выполняется на GPU (либо на CPU если карта не поддерживается), при этом без использования С++ и без необходимости знать синтаксис шейдеров.
Конечно же, имеются ограничения и недочёты. Нельзя использовать ссылочные типы данных (ни классы, ни массивы), только структуры и встроенные в ILGPU типы. Последний раз когда я работал с этой библиотекой, там была поддержка только карт NVidia, ну и дебаг возможен был только при запуске кода на CPU либо танцы с бубнами в профилировщике от NVidia.
Так что стоит сказать что и в этом направлении C# двигается (хоть и силами скромного комьюнити).
P.S. очень уж порадовало то, что эта штука в итоге кроссплатформенная, и оооочень много времени сэкономило, так как данные были большие (гиперспектральные изображения на 5--700 МБ), и некоторые расчёты могли занимать 40 минут на CPU (против 3-4 секунд на GPU, и откуда взялся этот выигрыш в 600 раз я не осмелюсь объяснять).