Re[39]: А С++ то схлопывается...
От: lpd Черногория  
Дата: 19.11.19 20:23
Оценка:
Здравствуйте, so5team, Вы писали:

S>У вас были аргументы? Помилуйте, где же? Дайте ссылочку, а то у меня ощущение, что упустил что-то важное.


Изначально я в данную ветку стриггерился на ускорение C++17, которое alex_public привел как решающий аргумент (хотя он потом написал, что не считает это ускорение важным).
Мой аргумент в том, что логические проблемы не решаются синтаксисом языка: ни move-семантикой, но unique_ptr<>. Удаление объекта — это часть логики программы, и она не всегда связана с удалением переменной, которое относится к синтаксису. Ты дал ссылку на статью, где рассматривается hello-world, в котором все как я и представлял. В простом случае удаление unique_ptr<> неплохо, я могу понять. Для тебя приоритетней "не забыть закрыть и удалить", и ты считаешь обертку unique_ptr<> оправданной, для меня же приоритетней явность удаления. Проблема удаления объектов у меня возникает только в сложных случаях, когда они используются в разных участках программы, обычно параллельно. Описание реального случая, где объект должен быть unique_ptr<> и ему нужен move, ты не привел.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
Отредактировано 19.11.2019 20:28 lpd . Предыдущая версия .
Re[40]: А С++ то схлопывается...
От: so5team https://stiffstream.com
Дата: 19.11.19 20:30
Оценка: +3
Здравствуйте, lpd, Вы писали:

lpd>Для тебя приоритетней "не забыть закрыть и удалить", и ты считаешь обертку unique_ptr<> оправданной, для меня же приоритетней явность удаления.


У вас из-за незнания предмета разговора возникает ощущение наличия альтернативы, которой, на самом-то деле, и нет. Использование unique_ptr и есть то самое явное удаление. В отличии от "явного удаления", которое в вашем случае обеспечивается лишь скрупулезностью разработчика.

lpd>Проблема удаления объектов у меня возникает только в сложных случаях, когда они используются в разных участках программы, обычно параллельно. Описание реального случая, где объект должен быть unique_ptr<> и ему нужен move, ты не привел.


Мне кажется, я привел здесь гораздо больше примеров кода, чем вы, smeeld и Pzz вместе взятые. И если вы, в силу незнания предмета, не понимаете приведенных примеров, то это не проблема примеров.
Re[39]: А С++ то схлопывается...
От: PM  
Дата: 19.11.19 20:54
Оценка:
Здравствуйте, so5team, Вы писали:

S>В С++ очень легко получить просадку производительности. Например, используя такие невинные, на первый взгляд, вещи, как shared_ptr<T>{new T()}, или задействуя std::regex, или вызывая std::vector::push_back в цикле без предварительного reserve(), или даже применяя std::unordered_map в каких-то сценариях. Или написав return std::move(some_object).


Стоит заметить, что также легко получить квадратичную сложность при вызове `std::vector::reserve()` в цикле. Например, при ручной очистке контейнера, добавленной чтобы избежать переполнения стека при автоматическом вызове деструкторов: https://www.reddit.com/r/cpp/comments/duh3q6/json_for_modern_c_version_372_released_json/f76wwic/

Повезло, что это проект с открытыми источниками, ошибку быстро заметили и уже исправили:
https://github.com/nlohmann/json/issues/1837

Лучшее враг хорошего, а C++ реально сложный
Re[40]: А С++ то схлопывается...
От: so5team https://stiffstream.com
Дата: 20.11.19 05:34
Оценка: +3
Здравствуйте, PM, Вы писали:

PM>Лучшее враг хорошего, а C++ реально сложный


Это да. Поэтому не видя кода сложно судить о том, что именно стало причиной отставания C++ в скорости.

С другой стороны, сам факт того, что у новичка с бэкграундом в функциональщине сходу получилось написать более быстрый код на Rust, чем на C++, говорит не в пользу C++.
Re[40]: А С++ то схлопывается...
От: удусекшл  
Дата: 20.11.19 07:48
Оценка:
Здравствуйте, PM, Вы писали:

PM>Стоит заметить, что также легко получить квадратичную сложность при вызове `std::vector::reserve()` в цикле. Например, при ручной очистке контейнера, добавленной чтобы избежать переполнения стека при автоматическом вызове деструкторов: https://www.reddit.com/r/cpp/comments/duh3q6/json_for_modern_c_version_372_released_json/f76wwic/


Хм. Не совсем понял, в чем проблема именно с reserve
Пишут:

First, your destructor is O(N²). This is a critical DoS vulnerability. This is how it works:

~basic_json() calls m_value.destroy(m_type);

destroy(..) creates a std::vector on stack (unconditionally, which is already pretty bad, but whatever), probably to avoid stack overflow in case of an extremely deep Json, but let's take a look at the following example somewhere in the document: [1, [2, [3, [4, ... [1000000, 1000001]... ]]]]


Насколько я понял, destroy вызывает также destroy для вложенных объектов, и везде создается временный вектор. Под вектор выделяется некоторое, достаточно небольшое, пространство на стеке. Под элементы же вектора место выделяется в куче. Причем тут квадратичная сложность именно из-за reserve, не понял. Тут проблема в том, что решили использовать рекурсию вместо цикла с очередью — да, это обычно проще, и обычно никто особо не заморачивается.

И было бы интересно сравнить работу с таким же json'ом в чистой сишечке, на джаве и на расте
Re[36]: А С++ то схлопывается...
От: удусекшл  
Дата: 20.11.19 07:50
Оценка:
Здравствуйте, smeeld, Вы писали:


S>В тех примерах руками дропать объекты есть неверно, это верно. Там unique_ptr и подобная муть оправдана, как и в любом хеллоуворлде. В масштабных же системах-это очень большая редкость, когда мы можем допустить автоматическое уничтожение объекта, уничтожение его фактом уничтожения других объектов, скручивания стека, etc. В подавляющем большинстве случаев, необходимость уничтожить объект появляется при определённом стечении обстоятельств, самых разных, чаще всего поступающих извне системы, внешних (сигналы из железок, события с других сервисов etc). Можно юзать unique_ptr, но придётся делать ему reset, что ничем от close/free не отличается. Так зачем оно всё тогда нужно? Чтоб быть модным и молодёжным C++-ником?


Можно юзать, а можно не юзать. Важно понимать, где инструмент применим, а где нет
Re[37]: А С++ то схлопывается...
От: smeeld  
Дата: 20.11.19 11:25
Оценка: :)))
Здравствуйте, so5team, Вы писали:

S>Знаете что? А давайте вы хоть каким-нибудь образом докажите, что имеете отношение к разработке на C++ чего-то объемом больше 10KLOC.


Это доказывается пониманием того, что unique_ptr-это рюшка, применимая только в хеллоуворлдах. Чего не понимате Вы. Что и выдаёт в Вас именно того самого хеллоуворлдщика.
Re[37]: А С++ то схлопывается...
От: smeeld  
Дата: 20.11.19 11:27
Оценка: :)))
Здравствуйте, Nuzhny, Вы писали:

N>Ты ещё скажи, что автоматическое отпускание мьютексов и закрытие файлов — это плохо.


Это не плохо, там где это надо, в хеллоуворлдах, на которых специализируются местные C++-гуру. В большинстве же случаев, автомат просто не нужен, он не просто не нужен, его там не должно быть.
Re[38]: А С++ то схлопывается...
От: student__  
Дата: 20.11.19 11:34
Оценка:
Здравствуйте, smeeld, Вы писали:
S>Это не плохо, там где это надо, в хеллоуворлдах, на которых специализируются местные C++-гуру. В большинстве же случаев, автомат просто не нужен, он не просто не нужен, его там не должно быть.
Это почему же "его там не должно быть"? А если таки будет, то что случится? Поподробнее, пожалуйста.
Re[41]: А С++ то схлопывается...
От: PM  
Дата: 20.11.19 11:50
Оценка:
Здравствуйте, удусекшл, Вы писали:

У>Хм. Не совсем понял, в чем проблема именно с reserve

У>Пишут:

У>Насколько я понял, destroy вызывает также destroy для вложенных объектов, и везде создается временный вектор. Под вектор выделяется некоторое, достаточно небольшое, пространство на стеке. Под элементы же вектора место выделяется в куче. Причем тут квадратичная сложность именно из-за reserve, не понял. Тут проблема в том, что решили использовать рекурсию вместо цикла с очередью — да, это обычно проще, и обычно никто особо не заморачивается.


По второй ссылке в комментариях к исправлению отвечают на этот вопрос:

If you reserve in a loop with a slowly increasing size, you'll get an allocation pattern like this:

2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32
If you don't reserve, then you'll get an allocation pattern like this, assuming a growth factor of 4:

4 16 64
Each time you call reserve(), you have an allocation, several default constructors (which may be trivial), several copies, several destructors (which may be trivial), and a deallocation. The only time you should reserve inside a loop is when you know the final size up front, or you know that it's a few items of large size, so you'll get a better allocation pattern than the built-in growth factor.


У>И было бы интересно сравнить работу с таким же json'ом в чистой сишечке, на джаве и на расте


Наверно кто-то таким вопросом задавался уже, должны быть сравнения. Для С и C++ есть https://github.com/miloyip/nativejson-benchmark

Например, упомянутое выше исправление было основано на результатах https://github.com/lovasoa/bad_json_parsers
Re[33]: А С++ то схлопывается...
От: alex_public  
Дата: 20.11.19 11:52
Оценка:
Здравствуйте, Skorodum, Вы писали:

_>>Только вот GPL — это уж точно не свободная лицензия. )))

S>KDE распространяло Qt под какой-то более "свободной" лицензией?

Я про KDE ничего не знаю (кроме того, что это проигравший конкурент Gnome, написанный на Qt). Я говорю о том, что в не таком далёком прошлом Qt распространялась только по двум несвободным лицензиям: GPL и коммерческая. И только относительно недавно стала доступна полусвободная (LGPL) лицензия.
Re[31]: А С++ то схлопывается...
От: alex_public  
Дата: 20.11.19 11:56
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>>>

НС>>>тем меньше серверов надо оплачивать — прямая бизнес-выгода.

_>>И? ) Эти мои слова как-то противоречат каким-то другим моим словам или что? )))
НС>Эти слова демонстрируют, что ты первый начал обсуждать экономику, а когда аргумент оказался так себе начал переводить стрелки.

Ещё раз повторюсь: я не против обсуждать вопрос с любой стороны. Только надо при этом уточнять, что речь именно об этой стороне. Т.е. в контексте нашей беседы, всё же с технической стороны никаких "упирается в БД" не существует, правильно? )

_>>Повышенное отжирание памяти Java приложениями в сравнение с нативными — это насколько избитая тема с таким множеством различных тестов,

НС>Речь шла не про отжирание вообще, а конкретно про рекордсеты.

А что, они там по твоему в итоге не отображаются на объекты Java, а обрабатываются прямо в бинарных блоках, пришедших от СУБД? )))
Re[38]: А С++ то схлопывается...
От: so5team https://stiffstream.com
Дата: 20.11.19 12:04
Оценка: +1
Здравствуйте, smeeld, Вы писали:

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


А это самое понимание того, что "unique_ptr-это рюшка, применимая только в хеллоуворлдах" оно чем доказывается? Вашим авторитетным анонимным мнением?
Re[39]: А С++ то схлопывается...
От: dsorokin Россия  
Дата: 20.11.19 12:29
Оценка:
Здравствуйте, so5team, Вы писали:

S>В этом смысле показательно ваше упоминание std::function: если вы его активно используете для хранения лямбд с непустым списком захвата, то, вероятно, вы используете динамическую память сами того не подозревая.


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

У меня процентов на 90 код состоит из сплошных шаблонов, что неплохо для "новичка", я считаю. Замыкания сохраняются как есть по максимуму, и лишь в единичных осознанных случаях они намеренно уходят в кучу через std::function.

На самом деле, у меня два типа сильно связанных задач. Я так понял, что для одного типа задач код на Rust окажется, скорее всего, быстрее в силу природы Rust, потому что там очень активно используется семантика перемещения для замыканий. Однако, для меня сейчас важнее второй тип (неозвученных) задач, из-за которых собственно я и заинтересовался переписыванием на С++. Там уже нужна семантика именно копирования для замыканий. Окончательных замеров пока нет, но промежуточные результаты, полученные для GCC, дают некоторую надежду, что в мною написанном коде для С++ может быть сохранен паритет с Rust. Так что, еще не вечер!
Re[40]: А С++ то схлопывается...
От: so5team https://stiffstream.com
Дата: 20.11.19 12:37
Оценка:
Здравствуйте, dsorokin, Вы писали:

S>>В этом смысле показательно ваше упоминание std::function: если вы его активно используете для хранения лямбд с непустым списком захвата, то, вероятно, вы используете динамическую память сами того не подозревая.


D>Не надо мне приписывать того, чего я не писал.


Не приписываю, у меня стоит "если".

D>У меня процентов на 90 код состоит из сплошных шаблонов, что неплохо для "новичка", я считаю.


Поскольку кода и условия задачи никто не видел, то "я считаю" здесь ключевое.
Re[39]: А С++ то схлопывается...
От: dsorokin Россия  
Дата: 20.11.19 12:39
Оценка:
Здравствуйте, so5team,

Просто первая реакция была "Все пропало", но сейчас я понял, что неправильно интерпретировал полученные результаты.
Re[38]: А С++ то схлопывается...
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 20.11.19 12:41
Оценка: +3
Здравствуйте, smeeld, Вы писали:

N>>Ты ещё скажи, что автоматическое отпускание мьютексов и закрытие файлов — это плохо.

S>Это не плохо, там где это надо, в хеллоуворлдах, на которых специализируются местные C++-гуру. В большинстве же случаев, автомат просто не нужен, он не просто не нужен, его там не должно быть.

Нууу, это всё так себе. Не знаю про многомиллионные монолиты, но можно посмотреть на типичный С код в том же ffmpeg (например, ffplay.c), чтобы полюбить С++ и автоматическое освобождение ресурсов. Код там хорошо структурирован в ООП стиле, структура в принципе понятна. Но есть частности, где логика усложняется и мы получаем либо дублирование кода, либо связки из goto, в которых с полпинка не разобраться. Я как раз имел "счастье" переписывания этого добра на С++, кода стало меньше, он стал читабельнее. Тесты никакой деградации по производительности не выявили, она была плюс-минус одинаковая.
Главное отличие, что при правильном проектировании области видимости и владения переменных автомат срабатывает не где-то непонятно где волшебным образом, а строго там где надо. Но срабатывает гарантированно, его невозможно забыть: для unique_ptr, для файлов, для мьютексов.
Re[40]: А С++ то схлопывается...
От: so5team https://stiffstream.com
Дата: 20.11.19 12:52
Оценка:
Здравствуйте, dsorokin, Вы писали:

D>Просто первая реакция была "Все пропало", но сейчас я понял, что неправильно интерпретировал полученные результаты.


Т.е. ложечки все-таки нашлись?
Re[41]: А С++ то схлопывается...
От: dsorokin Россия  
Дата: 20.11.19 13:04
Оценка:
Здравствуйте, so5team, Вы писали:

S>Т.е. ложечки все-таки нашлись?


Не совсем. Универсального решения из С++ у меня все же не получается. Только мудрецы всегда твердили, что универсальных методов не бывает.
Re[34]: А С++ то схлопывается...
От: Pzz Россия https://github.com/alexpevzner
Дата: 20.11.19 15:40
Оценка: +1
Здравствуйте, alex_public, Вы писали:

_>Я про KDE ничего не знаю (кроме того, что это проигравший конкурент Gnome, написанный на Qt). Я говорю о том, что в не таком далёком прошлом Qt распространялась только по двум несвободным лицензиям: GPL и коммерческая. И только относительно недавно стала доступна полусвободная (LGPL) лицензия.


А что, KDE таки проиграл гному?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.