Здравствуйте, lpd, Вы писали:
lpd>Вообще-то, оно применяется на каждом шагу в сжатии звука и графики/видео, томографии и всей DSP.
Я попробую в 25й раз — "интересует реальный бизнес кейс", а не вырванный кусок из него, производительность которого не говорит ровным счетом ничего — там банально считывание или пересылка данных может занимать в десятки раз больше времени чем DSP пофик на чем написанное.
Re[11]: Visual C# vs C++. Надо сравнить перспективы.
Здравствуйте, lpd, Вы писали:
_>>Здравствуйте, lpd, Вы писали: _>>Показываю конкретный и довольно известный случай. У тебя есть некий объект, который содержит некие тяжёлые ресурсы (большой объём памяти или ещё что-то) и автоматически управляет ими (в конструкторе/деструкторе). Так вот, расскажи как ты реализуешь создание и возврат (через return) данного объекта из функции без семантики перемещения? Чтобы и не надо было руками следить за временем жизни указателя и не было бы потери эффективности. lpd>В большинстве случаев все действительно большие объекты — глобальные, а в функции передается индекс или указатель на элемент. Либо это какие-то вычисления, и там все равно нет никакой инкапсуляции между объектами, а есть массив intов, и просто передается указатель из одной функции в другую.
Вот не стоит обобщать свой опыт на всех. Тем более, что большое число глобальных переменных обычно свидетельствует о не самой лучшей архитектуре приложения (если мы говорим про C++).
lpd>В любом случае, язык программирования это не столько краткое представление операций, сколько простая их запись. По-моему, проще иногда передать указатель и следить за временем жизни(которое нужно учитывать в любом случае), чем пользоваться rvalue ссылками.
Проще? ) Ты похоже не понял главную идею этой техники. Идея как раз в том, что компилятор использует предоставленную дополнительную информацию (типа конструктора перемещения) для оптимизации самого обычного кода, в который при этом не надо добавлять вообще ничего. Т.е. вот простейший пример:
auto make_object(int p)
{
if(p<0) return big_object();
big_object obj(p);
prepare(obj);
return obj;
}
auto obj=make_object(1024);
Вот прямо в таком коде будет работать семантика перемещения (если конечно у big_object определены соответствующие методы). А теперь покажи свой более простой вариант, только чтобы он тоже был без копирования... )
lpd>Давай конкретно: вот можешь описать случай с примером приложения и объекта, когда (бы) ты использовал move-семантику? хоть один?
Вообще то там миллион сценариев. Более того, частенько даже древний код можно существенно ускорить без переписывания, если подключить (перекомпилировать с опцией C++11 или старше) ему семантику перемещения. Но если ты хочешь, то я покажу самый банальный пример с явным вызовом:
Здравствуйте, AlexRK, Вы писали:
ARK>Напомню самое начало разговора: ARK>
А раз так, то на С++ как раз и следует писать только "реалтайм, тяжёлые вычисления, низкоуровневая работа с железом или ОС" (c), плюс кроссплатформенный и независимый по каким-то причинам от .NET софт.
ARK>Я считаю, что "standalone приложения" часто попадают в одну из последних категорий.
В таком случае из твоих взглядов напрямую следует, что автору данной темы однозначно следует посоветовать C++, т.к. у него в задание указано именно "standalone приложение". )
_>>Ну-ну) Т.е. ты веришь, что 7zip реализованный на C# сможет запаковать архив с той же скоростью, что и написанный на C++? ))) ARK>Опять вы не читаете. ARK>
Если их в принципе можно написать на C#, то они будут не хуже.
ARK>Так вот, я считаю, что код самого архиватора на C# в принципе написать нельзя. Ну, то есть наверное можно, но с хаками, которые уже будут выглядеть как С++.
Почему нельзя? ) В чём может быть проблема? Там всего лишь чтение бинарного файла в буфер, некие несложные преобразования над этим буфером и запись итогового буфера в новый файл. Да, это будет происходить в несколько раз медленнее, чем в аналогичном коде на C++, но у нас же тут не реалтайм или что-то подобное — пользователь спокойно подождёт архивации несколько лишних секунд. Т.е. приложение будет полностью работоспособное, хотя и более убогое.
ARK>А вот foobar2000, WinCDEmu, iTunes — все это на C# написать можно (если закрыть глаза на кроссплатформенность). И разницы с С++ не будет НИКАКОЙ.
Хы, кстати, а WinCDEmu случаем не ставит каких-нибудь там драйверов? ) Я сам им не пользовался, так что не в курсе. Но если ставит, то... )))
А foobar2000 кстати относится к почти реалтайм приложениям. Правда аудио потоки не очень тяжёлые, так что возможно хватит и C#, но ручаться бы не стал. )))
Re[11]: Visual C# vs C++. Надо сравнить перспективы.
Здравствуйте, Слава, Вы писали:
_>>Ну-ну) Т.е. ты веришь, что 7zip реализованный на C# сможет запаковать архив с той же скоростью, что и написанный на C++? ))) С>Да запросто. unsafe{...} и вперёд.
Ага, вперёд и получишь скорость раз в 5 медленнее. Вот уж как раз таких игры (обработки массивов данных) я проверял и сравнивал лично. И именно тут C# точно нечего ловить. )))
С>Кстати, 7zip до сих под андроид не портировали. Почему бы это? Потому что внутри него каша, а не код.
Почему именно 7zip (как продукт) не в курсе, может автор не работает с Андроидом, а может ещё что. Но архиваторов формата 7zip под Андроид полно.
Re[13]: Visual C# vs C++. Надо сравнить перспективы.
Здравствуйте, itslave, Вы писали:
_>>ОС, драйверы и т.д. — это уже другой вопрос, связанный с универсальным доступом к произвольному железу. А вот веб — это классическая прикладная задача, которая упрощённо (если не рассматривать промежуточную сетевую инфраструктуру) представляет собой классическое клиент-серверное приложение. В качестве сервера у нас тут выступают http-демоны (написанные на C/C++), кастомизируемые скриптами (которые пишутся на множестве языков) под конкретный сайт. А в качестве клиента у нас выступают браузеры (написанные на C++) и кастомизируемые скриптами I>Давай тогда будем точны в определениях, и начнем отличать веб серверы(которых полдесятка на весь мир) от веб сервисов(которые миллионы, и которые безусловно работают поверх веб серверов.
Согласен.
I>Дык вот, веб серверы сами по себе, конечным пользователям не нужны, равно как и отдельно взятые браузеры. Им нужны конкретные сервисы, построенные поверх веб серверов и работающие в веб браузерах. И вот внезапно оказывается, что рынок веб серверов ограничивается апачем, иисом и томкатом. А, еще есть Nginx. На рынке браузеров кстате тоже все уныло и предсказуемо.
Согласен.
I>А вот рынок веб сервисов совсем другой. Именно сервисы нужны конечным потребителям, и тут крутятся реальные деньги. Вот тут и начинается бизнесс прессинг — time to market, стоимость добавления фичи и так далее. И тут внезапно оказывается что С++ в этой сфере не нужен — он проигрывает по все показателям, абстрактные попугаи производительности в вакууме никого не интересуют.
Почти согласен. Разве что надо уточнить, что всё же не совсем не нужен — для случаев когда необходимые сервису физические сервера начинают измеряться в сотнях, преимущества C++ уже становятся актуальными для бизнеса. Реальные примеры я уже приводил в этой темке. Но естественно это совсем редкие случаи (если считать "в бизнесах", а не "в серверах" или "в пользователях сервиса").
Ну и конечно же с учётом заголовка нашей темы следует уточнить, что и C# тут является далеко не лидером. В данной области по прежнему царят динамические языки и основной передел популярности происходит как раз между ними (грубо говоря от нынешнего лидера php ко всяким там js/python/ruby).
Здравствуйте, Qbit86, Вы писали:
_>>А по твоему утверждение о том, что в VisualStudio навигация под коду реализуется компилятором C++ можно назвать чем-то иным кроме бреда? ) Q>Ты передёргиваешь и выдираешь из контекста. Проще говоря, до**ался до формулировок. Мне лень это тебе расписывать, а остальным вроде понятно.
Я в начале тоже подумал, что ты оговорился и просто обозвал анализатор кода IDE компилятором. Но с учётом того, что ты ниже стал защищать эту позицию всяческими рассуждениями про Roslyn и т.п., то похоже что это совсем не оговорка, а реальное не знание базовых вещей.
_>>про мифические недостатки которой ты тут писал. Q>Недостатки не мифические, а самые что ни на есть реальные, данные нам в ощущениях.
Данные тебе в ощущениях, вследствие твоего "знания" современных инструментов для C++. А если кто-то откроет C++ исходник в блокноте, то там у него навигация будет вообще "ужас, ужас". )))
_>>Ну можно конкретный пример кода, который у тебя работает не так как надо? ) И соответственно с описание того, как тебе надо. Q>Открываем файл «\boost_1_62_0\boost\graph\detail\adjacency_list.hpp», на строке 1832 вызов: Q>
Q>Нажимаем F12 Go To Definition чтобы перейти к сигнатуре и посмотреть, что там за типы. Вполне естественное желание, вроде ничего необычного, в C# такое часто делаю. Но в C++ вместо этого MSVS предлагает список методов, половина из которых вообще функции от четырёх аргументов. Q>Давай теперь ты рассказывай, какая у тебя IDE, какой компилятор, и как она осуществляет навигацию в этом примере.
У меня QtCreator. Открываю указанный файл, ставлю курсор на данный вызов add_edge (у меня это строка 1831 — чуть другая версия Boost'a), нажимаю F2 и оказываюсь на строке 2231 того же файла, где и определена соответствующая функция add_edge. Всё работает чётко и без всяких списков.
_>>Netbeans, CLion, Eclipse, QtCreator. Q>В окружающей меня реальности совокупная база пользователей этих «лидеров» на всех ОС меньше, чем у одной только Visual Studio на Windows. Но, может, в некой альтернативной реальности они стали лидерами, а Eclipse CDT перестал быть кривым **вном.
Значит в окружающей тебя реальности существуют исключительно оторванные от развития индустрии люди. VS была безусловно лидирующей IDE для C++ приблизительно в период 1995-2005 г. И кстати потеря лидерства была полностью предсказуема, в том числе и в руководстве MS — они сознательно пошли на это, фокусируясь исключительно на развитие .Net. Однако развитие индустрии (в первую очередь мобильных устройств, а теперь ещё окончание роста быстродействия процессоров) показало что эта их ставка была не верна. И несколько лет назад они сменили приоритеты и попытались восстановить свои старые позиции в мире нативной разработки. Однако образовавшееся гигантское отставание невозможно преодолеть за несколько лет. Хотя они безусловно стараются. Например ещё несколько лет назад на их компилятор C++ невозможно было взглянуть без слёз, настолько убого он поддерживал стандарт, не говоря уже о быстродействие. А сейчас уже неплохо подтянулись, хотя и по прежнему уступают gcc. Ну а с IDE судя по твоим слова (я не тестил VS17 и похоже правильно — только потеря времени) дела обстоят по прежнему печально.
Re[14]: Visual C# vs C++. Надо сравнить перспективы.
Здравствуйте, alex_public, Вы писали:
_>Почти согласен. Разве что надо уточнить, что всё же не совсем не нужен — для случаев когда необходимые сервису физические сервера начинают измеряться в сотнях, преимущества C++ уже становятся актуальными для бизнеса. Реальные примеры я уже приводил в этой темке. Но естественно это совсем редкие случаи (если считать "в бизнесах", а не "в серверах" или "в пользователях сервиса").
Почти согласен — зачастую в таких случаях С++ используется нишево, для того чтобы закрыть самые узкие места по перфомансу, синтегрировав в текущий солюшн. Весь codebase на С++ никто не кидается переписывать.
_>Ну и конечно же с учётом заголовка нашей темы следует уточнить, что и C# тут является далеко не лидером. В данной области по прежнему царят динамические языки и основной передел популярности происходит как раз между ними (грубо говоря от нынешнего лидера php ко всяким там js/python/ruby).
Ну тут сфера настолько широка, что я бы не стал так обобщать. Я ни разу не видел сурового ентерпрайза на пхп или node.js. С другой стороны, согласен — .NETa во всяких стартапчиках и сайты "за 3 дня под ключ" почти нет, там вес так как ты и сказал.
Здравствуйте, alex_public, Вы писали:
_>В таком случае из твоих взглядов напрямую следует, что автору данной темы однозначно следует посоветовать C++, т.к. у него в задание указано именно "standalone приложение". )
Почему нет, вполне возможно. Особенно если с прицелом на потенциальное использование в других ОС.
ARK>>Так вот, я считаю, что код самого архиватора на C# в принципе написать нельзя. Ну, то есть наверное можно, но с хаками, которые уже будут выглядеть как С++. _>Почему нельзя? ) В чём может быть проблема? Там всего лишь чтение бинарного файла в буфер, некие несложные преобразования над этим буфером и запись итогового буфера в новый файл. Да, это будет происходить в несколько раз медленнее, чем в аналогичном коде на C++, но у нас же тут не реалтайм или что-то подобное — пользователь спокойно подождёт архивации несколько лишних секунд. Т.е. приложение будет полностью работоспособное, хотя и более убогое.
Ну, это вопрос философский. Тут же не просто несколько лишних секунд, это функция от размера файла (и, кстати, скорее всего нелинейная). По моему мнению, архиваторы вполне подходят под категорию "системное ПО" и требуют максимального быстродействия, так что написание их на управляемых языках не очень разумно, так же, как и написание других системных вещей.
ARK>>А вот foobar2000, WinCDEmu, iTunes — все это на C# написать можно (если закрыть глаза на кроссплатформенность). И разницы с С++ не будет НИКАКОЙ. _>Хы, кстати, а WinCDEmu случаем не ставит каких-нибудь там драйверов? ) Я сам им не пользовался, так что не в курсе. Но если ставит, то... )))
А, да, точно. Ставит. Ну тогда C# не подходит. Хотя можно драйвер написать отдельно. Он, собственно, и так является отдельным приложением.
_>А foobar2000 кстати относится к почти реалтайм приложениям. Правда аудио потоки не очень тяжёлые, так что возможно хватит и C#, но ручаться бы не стал. )))
Для фубара быстродействия C# должно хватить. Это все как раз и определяется вашим первым шагом алгоритма. Если подходит только C/C++, то другие варианты отпадают, это логично.
Re[12]: Visual C# vs C++. Надо сравнить перспективы.
_>Вот прямо в таком коде будет работать семантика перемещения (если конечно у big_object определены соответствующие методы). А теперь покажи свой более простой вариант, только чтобы он тоже был без копирования... )
Честно говоря, я не понял, какой в данном случае метод нужно объявить у big_object, чтобы он стал rvalue-ссылкой. Нужно вызвать move и вернуть big_object &&.
Но ты привел типичный случай, который решается элементарно:
big_object *make_object(int p)
{
if (p<0) return new big_object;
big_object *obj = new big_object(p);
prepare(obj);
return obj;
}
big_object *obj=make_object(1024);
...
delete obj;
Я не понимаю, это что, из управляемых языков пошло, что "всех new и delete нужно исключить"? В случае с move-семантикой вызывающий код получает локальный объект на стеке(?), который обречен быть локальным. В случае с указателем, его можно отдать разным обработчикам.
lpd>>Давай конкретно: вот можешь описать случай с примером приложения и объекта, когда (бы) ты использовал move-семантику? хоть один?
_>Вообще то там миллион сценариев. Более того, частенько даже древний код можно существенно ускорить без переписывания, если подключить (перекомпилировать с опцией C++11 или старше) ему семантику перемещения. Но если ты хочешь, то я покажу самый банальный пример с явным вызовом: _>
Такое всегда решалось динамическим созданием объекта и записью указателя в вектор. В твоем случае при реаллокации вектора все большие объекты будут копироваться. И опять же, на мой взгляд указатель удобнее для дальнейшей работы(нескольких обращений к нему без копирования).
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, alex_public, Вы писали:
... кстате на счет десктопа. ДЛя дот нета существует множество библиотек визуальных компонентов, всякие там телерики, девекпрессы и прочие инфраджистики. Причем лидеры сапортят библиотеки под все реинкарнации десктопного дотнета: начиная от винформ и заканчивая UWP. КОнтролы красивые, катомизируемые и удобные. Можно взять к примеру грид, в 5 тыков мыши натянуть на него нужную тему, прикрутить пейджинг фильтрацию, сортировку, группировку с подсчетов агрегаций. А если грид оказался тормозной или некастомизируемый — купить другую либу контролов. В общем время разработки UI сокращается в десятки раз.
А как с этим в мире С++? Стандартные контролы от Qt — и все?
Здравствуйте, alex_public, Вы писали:
_>это совсем не оговорка, а реальное не знание базовых вещей.
Если у тебя проблемы с восприятием письменной речи, не стоит перекладывать их с больной головы на здоровую.
Q>>Недостатки не мифические, а самые что ни на есть реальные, данные нам в ощущениях. _>Данные тебе в ощущениях, вследствие твоего "знания" современных инструментов для C++.
В C++ огромное множество врождённых недостатков, независимых от «современных инструментов». Если топикстартер по твоему совету выберет C++, он просто хлебнёт **вна на ровном месте, по причинам совсем не обусловленным необходимостью.
_>Всё работает чётко
Прекрасно; а что насчёт препроцессора? Вот у тебя в библиотечном заголовочном файле `<boost/some_header.hpp>` определение функции `some_function()`: `#ifdef BOOST_SOME_DEFINE ... some_function ... #else ... some_function ... #endif`. Пользовательские файлы включают этот заголовок и как `#define BOOST_SOME_DEFINE ... #include <boost/some_header.hpp>`, и как `#undef BOOST_SOME_DEFINE ... #include <boost/some_header.hpp>`. Если ты откроешь заголовок — какая версия `some_function()` будет «активная»? Работает ли навигация внутри «неактивного» фрагмента? Если по F12 Go To Definition внутри открытого заголовочного файла перейти к объявлению/определению функции, к какому из этих двух вариантов перейдёт IDE?
_>>>Netbeans, CLion, Eclipse, QtCreator. Q>>В окружающей меня реальности совокупная база пользователей этих «лидеров» на всех ОС меньше, чем у одной только Visual Studio на Windows. Но, может, в некой альтернативной реальности они стали лидерами, а Eclipse CDT перестал быть кривым **вном.
_>Значит в окружающей тебя реальности существуют исключительно оторванные от развития индустрии люди.
Вполне может быть — в окружающей меня реальности окологеймдев. (Ну или что ты там подразумеваешь под «индустрией».) Но всё-таки: лидер (согласно alex_public) Eclipse CDT перестал бы кривым **вном, каким был несколько лет назад, когда я его в последний раз запускал?
Здравствуйте, Слава, Вы писали:
С>Можно использовать несколько языков в проекте. Только вот выбранный ранее язык определяет идиосинкразию предыдущих разработчиков к чему-то новому и отличному от милого их сердцам make c #DEFINE TRUE FALSE.
Вот не стоит обобщать на всех свои фобии. ) Скажем я спокойно использую несколько совсем разных языков (например C++ и Python) в одном проекте и вполне комфортно себя чувствую. И не думаю что являюсь каким-то исключением из правил в этом смысле. )))
С>Уж казалось бы — HPC. Куда там ffmpeg'у какому-то, или обработке voip, которая вся сводится к манипуляции текстовыми заголовками. И то — людям стало УДОБНЕЕ пользоваться не байтогрызным MPI с его высокомерным сообществом, а написать свой Apache Spark. Фреймворк для ВЫСОКОПРОИЗВОДИТЕЛЬНЫХ вычислений для Яве. На Яве, Карл!
И уж тем более не стоит рассказывать здесь сказки про мир HPC. Там до сих пор большинство народа живёт в мире Фортрана и Си. Самые продвинутые осторожно трогают C++. Плюс весьма популярен Python в качестве "системного клея" (вокруг C библиотек). Про какие-то иные инструменты там редко кто даже слышал. А уж на попытку протащить туда язык типа Java с его смешным быстродействием вообще ничего кроме улыбок ждать не придётся. )))
Re[13]: Visual C# vs C++. Надо сравнить перспективы.
_>>Вот прямо в таком коде будет работать семантика перемещения (если конечно у big_object определены соответствующие методы). А теперь покажи свой более простой вариант, только чтобы он тоже был без копирования... ) lpd>Честно говоря, я не понял, какой в данном случае метод нужно объявить у big_object, чтобы он стал rvalue-ссылкой.
Естественно конструктор перемещение. Т.е. банально добавить в класс big_object метод "big_object(big_object&& о) {}" и всё, семантика перемещения заработает для данного классса.
lpd>Нужно вызвать move и вернуть big_object &&.
Нет, никаких move не требуется, компилятор сам всё сделает для return. Да, и кстати если убрать auto в моём коде, то на его месте будет просто big_object, без всяких ссылок. Никакие rvalue ссылки в самом коде использовать не надо, в этом и смысл данной техники — работаем со всеми объектами (включая и тяжёлые) просто как с обычными int'ми. )))
lpd>Но ты привел типичный случай, который решается элементарно: lpd>
lpd>big_object *make_object(int p)
lpd>{
lpd> if (p<0) return new big_object;
lpd> big_object *obj = new big_object(p);
lpd> prepare(obj);
lpd> return obj;
lpd>}
lpd>big_object *obj=make_object(1024);
lpd>...
lpd>delete obj;
lpd>
Ну так и какой код выглядит сложнее и объёмнее, мой или твой? ) Ты же заявлял, что код с применением семантики перемещения существенно усложняется...
lpd>Я не понимаю, это что, из управляемых языков пошло, что "всех new и delete нужно исключить"? В случае с move-семантикой вызывающий код получает локальный объект на стеке(?), который обречен быть локальным. В случае с указателем, его можно отдать разным обработчикам.
Вообще то это как раз в управляемых языках сплошные new (и неявные фоновые delete), которые и вызывают значительную часть тормозов языка. Вследствие введения дополнительного уровня косвенности, который не даёт нормально работать кэшу процессора. А как раз в современном C++ уходят от всего этого в сторону использования локальных переменных на стеке, которые являются самым эффективным инструментом. Да, а семантика перемещения как раз полностью решает проблему с передачей этого "локального" объекта куда-то ещё.
lpd>>>Давай конкретно: вот можешь описать случай с примером приложения и объекта, когда (бы) ты использовал move-семантику? хоть один? _>>Вообще то там миллион сценариев. Более того, частенько даже древний код можно существенно ускорить без переписывания, если подключить (перекомпилировать с опцией C++11 или старше) ему семантику перемещения. Но если ты хочешь, то я покажу самый банальный пример с явным вызовом: _>>
lpd>Такое всегда решалось динамическим созданием объекта и записью указателя в вектор. В твоем случае при реаллокации вектора все большие объекты будут копироваться. И опять же, на мой взгляд указатель удобнее для дальнейшей работы(нескольких обращений к нему без копирования).
И именно такой подход существенно убивает производительность, т.к. добавляет лишний уровень косвенности.
P.S. Ты только не обижайся, но что-то ты сейчас демонстрируешь отсутствие целого набора базовых знаний (и современного стандарта языка и вопросов оптимизации под современные процессоры), необходимых для хорошего специалиста по C++.
Здравствуйте, itslave, Вы писали:
I>Здравствуйте, alex_public, Вы писали: I>... кстате на счет десктопа. ДЛя дот нета существует множество библиотек визуальных компонентов, всякие там телерики, девекпрессы и прочие инфраджистики. Причем лидеры сапортят библиотеки под все реинкарнации десктопного дотнета: начиная от винформ и заканчивая UWP. КОнтролы красивые, катомизируемые и удобные. Можно взять к примеру грид, в 5 тыков мыши натянуть на него нужную тему, прикрутить пейджинг фильтрацию, сортировку, группировку с подсчетов агрегаций. А если грид оказался тормозной или некастомизируемый — купить другую либу контролов. В общем время разработки UI сокращается в десятки раз. I>А как с этим в мире С++? Стандартные контролы от Qt — и все?
Ну т.к. стандартной GUI библиотек у C++ нет, то всё зависит от того, какую ты выбрал. Если это скажем Qt (в последнее время претендует на звание лидера в данной области) и базовых контролов не хватает (что довольно редко, т.к. в самой Qt всё крайне кастомизируемо), то можно глянуть например здесь: https://inqlude.org/index.html (там не только контролы, но и они в том числе). Лично мне из всего этого встречались только контролы для построения модных графиков и то только один раз.
Re[14]: Visual C# vs C++. Надо сравнить перспективы.
_>Естественно конструктор перемещение. Т.е. банально добавить в класс big_object метод "big_object(big_object&& о) {}" и всё, семантика перемещения заработает для данного классса.
OK, move-конструктор. Тем не менее, я считаю, что с ними слишком запутанные правила. Я бы предпочел, чтобы по вызывающему коду было понятно, что тут move, и не требовалось каждый раз смотреть определение класса.
lpd>>Но ты привел типичный случай, который решается элементарно: lpd>>
lpd>>big_object *make_object(int p)
lpd>>{
lpd>> if (p<0) return new big_object;
lpd>> big_object *obj = new big_object(p);
lpd>> prepare(obj);
lpd>> return obj;
lpd>>}
lpd>>big_object *obj=make_object(1024);
lpd>>...
lpd>>delete obj;
lpd>>
_>Ну так и какой код выглядит сложнее и объёмнее, мой или твой? ) Ты же заявлял, что код с применением семантики перемещения существенно усложняется...
Более короткий код не значит простой, кроме того: lpd>>В случае с move-семантикой вызывающий код получает локальный объект на стеке(?), который обречен быть локальным. В случае с указателем, его можно отдать разным обработчикам.
_>Да, а семантика перемещения как раз полностью решает проблему с передачей этого "локального" объекта куда-то ещё.
Как передать этот локальный объект в другой поток? он на стеке и может быть уничтожен, пока другой поток будет еще выполняться. С указателем это делается легко и непринужденно.
lpd>>>>Давай конкретно: вот можешь описать случай с примером приложения и объекта, когда (бы) ты использовал move-семантику? хоть один? _>>>Вообще то там миллион сценариев. Более того, частенько даже древний код можно существенно ускорить без переписывания, если подключить (перекомпилировать с опцией C++11 или старше) ему семантику перемещения. Но если ты хочешь, то я покажу самый банальный пример с явным вызовом: _>>>
lpd>>Такое всегда решалось динамическим созданием объекта и записью указателя в вектор. В твоем случае при реаллокации вектора все большие объекты будут копироваться. И опять же, на мой взгляд указатель удобнее для дальнейшей работы(нескольких обращений к нему без копирования).
_>И именно такой подход существенно убивает производительность, т.к. добавляет лишний уровень косвенности.
Ты что, всерьез заботишься о времени разыменования указателя? оно ничтожно, а в тех очень редких случаях, где играет роль, пишут просто вставки на ассемблере. Или как такой подход убивает производительность?
Большие объекты в векторе лучше не хранить из-за реаллокации при изменении размера и фрагментации после eraseов. Поэтому и в этом случае указатели удобнее.
Так что все еще необходим пример(желательно конкретного приложения, т.к. big_object это обычно по сути массив для вычислений, и редко что-либо иное, что нежелательно копировать), в котором нужна move-семантика. На мой взгляд — обычный C++ это баланс производительностью, удобством и простотой, с возможностью ручного ассемблера. А с move-семантикой теряется простота. Кроме того, вот я когда то достаточно написал программ на ассемблере, и мне с моим опытом не очевидно, как move-семантика реализована. Компилятор резервирует место на стеке, выходит из функции, а когда стек возвращается к передвинутой локальной переменной, пропускает этот кусок памяти? или как?
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, Qbit86, Вы писали:
_>>это совсем не оговорка, а реальное не знание базовых вещей. Q>Если у тебя проблемы с восприятием письменной речи, не стоит перекладывать их с больной головы на здоровую.
Уууу... Я бы на твоём месте постарался поскорее оставить в прошлом вопрос в котором откровенно накосячил. Но ты вместо этого продолжаешь оправдываться, да ещё и пытаешься какие-то переходы на личности делать... Раз так, то давай разберёмся окончательно с этим вопросом. И так вот твоя точная цитата:
В C++ это не так: выбираешь ли ты «Go To Declaration Ctrl+F12», или «Go To Definition F12» — он может выдать список. Потому что компилятор на «этапе чтения мной кода» (евпочя) не имеет достаточной информации; он будет её иметь, только когда я попытаюсь код вызвать, SFINAE, и всё такое.
Соответственно или ты тут нечаянно обозвал анализатор кода IDE компилятором (но тогда к чему были потом долгие рассуждения про Roslyn в роли анализатора кода?) или же у тебя тут наблюдается банальное незнание самых базовых вещей (что компилятор C++ не имеет никакого отношения к навигации по коду в VS). Каких-либо ещё вариантов интерпретации этой твоей цитаты быть не может. И оба данных варианта тебя совсем не красят.
Q>>>Недостатки не мифические, а самые что ни на есть реальные, данные нам в ощущениях. _>>Данные тебе в ощущениях, вследствие твоего "знания" современных инструментов для C++. Q>В C++ огромное множество врождённых недостатков, независимых от «современных инструментов».
Вот сразу видно хорошо аргументированное утверждение. )))
Q>Если топикстартер по твоему совету выберет C++, он просто хлебнёт **вна на ровном месте, по причинам совсем не обусловленным необходимостью.
Вообще то я не советовал ему именно C++. Перечитай моё сообщение повнимательнее.
Q>Прекрасно; а что насчёт препроцессора? Вот у тебя в библиотечном заголовочном файле `<boost/some_header.hpp>` определение функции `some_function()`: `#ifdef BOOST_SOME_DEFINE ... some_function ... #else ... some_function ... #endif`. Пользовательские файлы включают этот заголовок и как `#define BOOST_SOME_DEFINE ... #include <boost/some_header.hpp>`, и как `#undef BOOST_SOME_DEFINE ... #include <boost/some_header.hpp>`. Если ты откроешь заголовок — какая версия `some_function()` будет «активная»? Работает ли навигация внутри «неактивного» фрагмента? Если по F12 Go To Definition внутри открытого заголовочного файла перейти к объявлению/определению функции, к какому из этих двух вариантов перейдёт IDE?
Хы, ну такие то вещи давным давно работают корректно (всё же макросы заметно проще шаблонов). Навигация в таких случаях работает корректно в любом случае, т.к. она контекстная. Подсветка (неактивная ветка ifdef обычно подсвечивается серым фоном) же в таком случае чаще всего (т.к. подобные ifdef чаще всего применяются для кастомизации под конкретную ОС/компилятор) выбирается с помощью настроек проекта (добавление соответствующего макроса).
Q>Вполне может быть — в окружающей меня реальности окологеймдев. (Ну или что ты там подразумеваешь под «индустрией».) Но всё-таки: лидер (согласно alex_public) Eclipse CDT перестал бы кривым **вном, каким был несколько лет назад, когда я его в последний раз запускал?
Eclipse я лично не люблю за излишнюю монструозность и перегруженность интерфейса. И соответственно не использую его сейчас, т.к. появились инструменты получше. Но в то время, когда я его использовал, никаких существенных претензий к его анализатору кода (а соответственно и навигации, автодополнению, рефакторингу и т.п.) у меня не было. Не думаю, что с тех пор они что-то ухудшили в этом смысле, скорее наоборот только улучшили. Так что в контексте нашей беседы думаю что и он проявит себя намного лучше твоей голой VS.
Здравствуйте, Qbit86, Вы писали:
V>>Так ты, действительно, не понимаешь? Q>у тебя illusion of transparency.
Да не отмазывайся, ты накосячил в рассуждених пару постов назад, дополнительно усугубив это тем, что не обратил внимание на свой косяк даже после намёка. Неожиданно, прямо скажем.
Ты, вообще, программист или где? Сосредоточься, или не пиши.
V>>Потому что "параметрический полиморфизм" (якобы параметрический полиморфизм) для ref-типов реализован в C# именно таким образом. V>>Т.е., нет никакого смысла опираться на некий T, потому что доступен только лишь IBarable. И вся "польза" от такого полиморфизма — в исключении проверок/приведений типов в исходнике пользователя.
Q>Во-первых, у пользователя библиотеки интерфейс IBarable может быть реализован value-типом.
Ну вот, ЧТД.
Продолжаем откровенно притормаживать.
1. Было написано (специально):
для ref-типов
2. Большинство алгоритмов даже из базовой библиотеки не работают на value-типах, кроме случаев, когда этот тип является элементом контейнера (или последовательности), т.е. кроме тех случаев, когда НИКАКИХ методов у целевого типа T не вызывается. А у тебя в примерах идёт вызов метода именно у типа Т.
Собсно, вообще таких алгоритмов мало, которые можно выразить в дотнете для value и ref-типов в генериках и они будут корректно работать в обоих случаях. Я одно время на этом собаку съел, в поисках классов таких алгоритмов, которые, таки, работают в обоих случаях и в попытках сформулировать ограничения на такие алгоритмы. А у тебя какой-то детсад прёт, сорри: "а вот бывает... а вот если...".
Q>Во-вторых, в сигнатуре динамически полиморфного метода ты можешь указать только один тип; а в констрейнтах дженерика несколько. Соответственно, пользовательская структура тоже реализует несколько интерфейсов, но без единой иерархии с одним «общим» интерфейсом.
И опять рука-лицо.
Потому что для случая дотнета это как раз абсолютно однофигственно — ты можешь ввести тот самый исскуствепнный "общий" интерфейс и выразить ограничения через него. И абсолютно ничего ни в одном месте, где будет или использована такая структура (или уже была исопльзована), не поломается и не изменится. Ни-че-го.
Q>Покажи, как на C++ будет выглядеть этот более общий вариант.
Т.е., нет никакого смысла опираться на некий T, потому что доступен только лишь IBarable. И вся "польза" от такого полиморфизма — в исключении проверок/приведений типов в исходнике пользователя.
Т.е., С++ вариант отличается от варианта C# именно приведением типов в исходнике пользователя. Если такое приведение типов невозможно, компиляция не состоится, ву-а-ля. И Решарпер прекрасно всё подскажет даже внутри шаблона, кста.
===========
Предлагаю завязывать, бо мне уже трудно сдерживать откровенное глумление...
Столько было пафоса и такой пффф... Не могу отучить себя реагировать на такую комбинацию ))
Re[15]: Visual C# vs C++. Надо сравнить перспективы.
Здравствуйте, lpd, Вы писали:
_>>Естественно конструктор перемещение. Т.е. банально добавить в класс big_object метод "big_object(big_object&& о) {}" и всё, семантика перемещения заработает для данного классса. lpd>OK, move-конструктор. Тем не менее, я считаю, что с ними слишком запутанные правила. Я бы предпочел, чтобы по вызывающему коду было понятно, что тут move, и не требовалось каждый раз смотреть определение класса.
Ты сказал компилятору, что данный класс умеет перемещаться и соответственно компилятор будет вставлять эту оптимизацию везде, где только сможет. Плюс, в тех местах, где он сам не может, ты можешь ему указать это руками с помощью функции move.
_>>Ну так и какой код выглядит сложнее и объёмнее, мой или твой? ) Ты же заявлял, что код с применением семантики перемещения существенно усложняется... lpd>Более короткий код не значит простой, кроме того:
В данном случае он именно что более простой — имеет буквально такой же вид, какой был бы в случае int вместо big_object.
_>>Да, а семантика перемещения как раз полностью решает проблему с передачей этого "локального" объекта куда-то ещё. lpd>Как передать этот локальный объект в другой поток? он на стеке и может быть уничтожен, пока другой поток будет еще выполняться. С указателем это делается легко и непринужденно.
Организация многопоточной работы — это отдельная большая и сложная тема со многими вариантами решения. Но я могу тут сразу заметить, что семантика перемещения просто идеально ложится на одно из самых лучших решений в этой области под названием "модель акторов". )
_>>И именно такой подход существенно убивает производительность, т.к. добавляет лишний уровень косвенности. lpd>Ты что, всерьез заботишься о времени разыменования указателя? оно ничтожно, а в тех очень редких случаях, где играет роль, пишут просто вставки на ассемблере. Или как такой подход убивает производительность?
Дело не в разыменования указателя, а в технике работы кэща процессора. В случае обхода одного непрерывного массива данных у тебя все запрашиваемые данные будут уже в кэше, что ускорит работу в разы. А в случае использования массива указателей они практически наверняка (ну если ты там не используешь именно для этих данных какой-нибудь специальный аллокатор на пуле) будут указывать на различные непоследовательные участки памяти...
lpd>Большие объекты в векторе лучше не хранить из-за реаллокации при изменении размера и фрагментации после eraseов. Поэтому и в этом случае указатели удобнее.
При таких условиях задачи надо вообще использовать другой контейнер. )))
lpd>Так что все еще необходим пример(желательно конкретного приложения), в котором нужна move-семантика.
Что значит "нужна"? )
Вот есть у тебя некое красивое, но не идеально оптимизированное C++ приложение (встречаются копирования объектов и т.п.). Ты добавил в него поддержку семантики перемещения и получил ускорение его работы на сколько то там процентов при сохранение внешнего вида кода. Это как считается, "нужна" или нет? )
Или вот скажем у тебя есть хорошо оптимизированное приложение написанное на чистых указателях, где ты страдаешь с ручным отслеживанием всего этого дела. Ты переписал это всё на современном C++, сохранив старую производительность и при этом полностью забыл про все ужасы ручных указателей. Это считается "нужна" или нет? )
Re[16]: Visual C# vs C++. Надо сравнить перспективы.
Здравствуйте, alex_public, Вы писали:
_>Здравствуйте, lpd, Вы писали:
lpd>>Как передать этот локальный объект в другой поток? он на стеке и может быть уничтожен, пока другой поток будет еще выполняться. С указателем это делается легко и непринужденно.
_>Организация многопоточной работы — это отдельная большая и сложная тема со многими вариантами решения. Но я могу тут сразу заметить, что семантика перемещения просто идеально ложится на одно из самых лучших решений в этой области под названием "модель акторов". )
Модель акторов это очень хорошо. Однако она не всегда применяется, а передача объекта в другой поток встречается на каждом шагу, и тут указатели удобны.
_>>>И именно такой подход существенно убивает производительность, т.к. добавляет лишний уровень косвенности. lpd>>Ты что, всерьез заботишься о времени разыменования указателя? оно ничтожно, а в тех очень редких случаях, где играет роль, пишут просто вставки на ассемблере. Или как такой подход убивает производительность?
_>Дело не в разыменования указателя, а в технике работы кэща процессора. В случае обхода одного непрерывного массива данных у тебя все запрашиваемые данные будут уже в кэше, что ускорит работу в разы. А в случае использования массива указателей они практически наверняка (ну если ты там не используешь именно для этих данных какой-нибудь специальный аллокатор на пуле) будут указывать на различные непоследовательные участки памяти...
Это при условии, что контейнер, все-таки вектор, да еще и обходится последовательно, что не столь типично.
_>Вот есть у тебя некое красивое, но не идеально оптимизированное C++ приложение (встречаются копирования объектов и т.п.). Ты добавил в него поддержку семантики перемещения и получил ускорение его работы на сколько то там процентов при сохранение внешнего вида кода. Это как считается, "нужна" или нет? )
Если нужно ускорение работы на несколько процентов, то я бы использовал ассемблер.
_>Или вот скажем у тебя есть хорошо оптимизированное приложение написанное на чистых указателях, где ты страдаешь с ручным отслеживанием всего этого дела. Ты переписал это всё на современном C++, сохранив старую производительность и при этом полностью забыл про все ужасы ручных указателей. Это считается "нужна" или нет? )
Ручные указатели ужасом мне не представляются, в отличие от всего свода правил по rvalue-ссылкам.
В принципе, если кто-то действительно может быстрый и понятный(хотя бы ему) код с move-семантикаой, то это само по себе не плохо. Кому-то вот, например нравится ассемблер, и он будет писать код, который ему нравится со вставками на ассемблере. Другой добавит туда perl6, который ему нравится.
Я к тому, что главное не использовать move-семантику только потому, что она в новом стандарте, а значит, типа, must-have.
Я еще редактировал предыдущий пост недавно, и добавлял:
На мой взгляд — обычный C++ это баланс производительностью, удобством и простотой, с возможностью ручного ассемблера. А с move-семантикой теряется простота. Кроме того, вот я когда то достаточно написал программ на ассемблере, и мне с моим опытом не очевидно, как move-семантика реализована. Компилятор резервирует место на стеке, выходит из функции, а когда стек возвращается к передвинутой локальной переменной, пропускает этот кусок памяти? или как?
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Здравствуйте, alex_public, Вы писали:
_>Ну т.к. стандартной GUI библиотек у C++ нет, то всё зависит от того, какую ты выбрал. Если это скажем Qt (в последнее время претендует на звание лидера в данной области) и базовых контролов не хватает (что довольно редко, т.к. в самой Qt всё крайне кастомизируемо)
Если взять https://www.devexpress.com/products/net/controls/winforms/grid/ и сравнить со стандартным qt гридом, то сколько % фичеров покроет грид qt из коробки? А предлагает ли https://inqlude.org/index.html что нить сравнимое?