Pull to refresh

Comments 22

Выглядит как панацея и серебряная пуля вместе взятые. Я правильно понимаю, что вы при каждой потере ссылки проходите до рута чтобы понять, не была ли она последней? Если да, то это медленно. Если нет, то не понятно, как это защищает от циклических ссылок.
Есть ли замеры скорости работы? Потребления памяти?
>> Выглядит как панацея и серебряная пуля вместе взятые.
Нет, это не панацея, есть свои недостатки производительности
>> Я правильно понимаю, что вы при каждой потере ссылки проходите до рута чтобы понять, не была ли она последней?
Не совсем, я бегу не всегда от рута, а от места где поменялась ссылка, так я прохожусь по части графа, а не по всему графу от рута… Добавлю в статью картинку попозже…
Да это медленно, но в отличии от обычного Garbage Collector-а этот pointer детерминистически pointer ведет себя детерминированно

Замеров по памяти и скорости работы и памяти еще не делал, намереваюсь сделать…
Некоторые примеры показывают, что паузы с GC достигают 300мс на 1.5Гб памяти на мелких объектах.

Стоит бы сравниваться с Боехм GC

<зануда>Вообще-то поддержка сборщик мусора в c++ есть _https://en.cppreference.com/w/cpp/memory garbage collector support</зануда> А если серьёзно, то действительно интересуют цифры производительности, ну и какие-то пограничные случаи рассмотреть бы

Ну declare_reachable и undeclare_reachable не трекают связи между объектами, я же их трекаю через специальные методы connectToRoot и disconnectFromRoot, которые я налижу на генератор и добавлю к библиотеке, пока что их необходимо прописывать руками (
Единственное что позволили бы мне эти методы сделать reachable unreachable sematic более явной

Из граничных условий я виже пока, что не отработает в lambda-выражениях при сохранении lambda-функций в std::function так как надо получить достук к установки рута для std::function и контекстно захваченых объектов
Вывод: операторы присваивания и выход объекта из области видимости будут очень дорогими и недетерминированными по времени.
Вполне детерминироваными, так как если заранее просчитать все связи можно сказать когда объекты удалятся
Для обычного Garbage Collector-а время его запуска непредсказуемо и время выполнения непредсказуемы
Но сколько объектов затронет такая сборка, сказать заранее невозможно. Может на нём висит граф из тысяч объектов, которые тоже зачистить надо?
Да, сказать невозможно заранее… Но это цена которую платит разработчик за удобство использования
Если вы собираетесь писать небольшой генератор, почему бы не нацелить генератор на анализ графа сильных ссылок (для предотвращения циклов) ещё в фазе кодогенерации? Ещё один момент: мне попадались статьи Херба Саттера на данную тему, вам интересно было бы прочитать? Он нацеливался на добавление нового смартпойнтера в стандартную библиотеку (если я не путаю), но не довёл до этого.
Да, я видел его выступления на тему статического анализа утечек памяти в C++
Безумно интересно, но мне кажется одно другому не мешает…
У нас в C++ будет:
1) Raw Pointers — наивысшая производительность, но возможна утечка памяти при неаккуратном обращении
2) Smart Pointer — совсем малость хуже производительность, лучше с управлением памятью, но опять же при неаккуратном обращении возможны утечки памяти… Чтобы их исключить необходимо хорошо организовывать свои структуры данных и flow программы
3) Garbage Collector Pointer — наихудшая производительность из всех возможных, но гарантированное разрушение объектов во вполне определенных местах в программе. Не нужно разбираться со структурой программы добавляй и он просто работает
4) Static Analyze Memory Leaks — никаких накладных расходов, но не все случаи охватываются

И пусть люди выбирают в зависимости от задачи что им больше подходит
Выступление Херба про конкретный проект https://github.com/hsutter/gcpp называлось Lifetime Safety By Default — Making Code Leak-Free by Construction, он его делал примерно 3 года назад на CppCon, слайды здесь, видео здесь — это не про статический анализ, поэтому решил привести ссылки. Пользуясь случаем, про raw pointers (*) и references (&). Некоторое время назад я программировал, избегая их использования, возвращая результатами функций смартпойнтеры и передавая их аргументами, например, как в getChild в вашем коде. Однако, сейчас я пересмотрел этот подход в сторону рекомендаций Core Guidelines, конкретно F.7: For general use, take T* or T& arguments rather than smart pointers, F.60: Prefer T* over T& when “no argument” is a valid option и R.30: Take smart pointers as parameters only to explicitly express lifetime semantics. Херб подробно разбирает этот вопрос в GotW #91 Solution: Smart Pointer Parameters. Конечно, открытие «сырых» ссылок / указателей упрощает злоупотребление, идея в том, что злоупотребления пресекаются статическим анализатором (которому в таком контексте нужно не точно анализировать все возможные варианты lifetime management, а предупреждать о нарушениях конкретной модели lifetime management, предлагаемой в Core Guidelines). Насколько хороши в этом плане существующие анализаторы вроде clang-tidy, сейчас сказать не могу (надо когда-нибудь разобраться, конечно).
Ужасно. Если не можете разобраться с shared_ptr/weak_ptr, программируйте на си-шарпе, зачем вам c++?
Я прекрасно разбираюсь shared_ptr/weak_ptr, cс чего вы взяли что я не разбираюсь?
Ничего ужасного, это один из вариантов как можно писать код и не заморачиваться со структурой программы, естественно этот вариант не подходит для высокопроизводительных программ, но если производительность не интересует, а интересует быстро реализовать задачу то вполне подходит и такой pointer )
Очевидно, что далеко не прекрасно. И, как соотносятся фразы «Но вот если у вас более сложная иерархия объектов и очень сложно понять» и «интересует быстро реализовать задачу то вполне подходит и такой pointer )»? По-моему, они явно не об одном и том же.
О многопоточности я вообще молчу.
Я не могу понять почему такая острая критика, за мелкие неточные выссказывания в статье?
Как по этим фразам можно считать разбирается человек или нет?
Фразы которые вы привели лишь о случаях в которых можно было бы использовать данный тип объекта

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

Я бы сказал, что всякие unique_ptr, shared_ptr, weak_ptr — это явно костыли эмулирования GC.
Вообще, все зависит от сложности доменной модели — где пойдут и костыли, а где нужно задуматься о велосипеде полнго GC.
Блин, зачем же ) После выстрела в ногу на велосипеде же кататься не получится ))
Прошу прощения за граммар-нацизм, но, блин, что мешает перед постингом текста более-менее крупного размера скопировать текст в Ворд, который бы вывел на чистую воду добрый десяток всяких опечаток, ошибок, и отсутствующих запятых? Хабр всегда был ресурсом интеллектуальных и образованных людей, и видеть тут ошибки уровня «рассходы» и «используем-то» глазам кроваво…
Т.е. весь сыр-бор из-за того, что в дочернем объекте зачем-то хранится умный указатель на родителя, вместо просто указателя? По определению, дочерний объект не может существовать без родительского, потмоу что при удалении родительского сперва удаляются его дочерние (удаляется контейнер, содержащий умные указатели на дочерние объекты). Если дочернему объекту разрешено менять родителя, то всё-равно простой/умный указатель будут или обнуляться или модифицироваться.
В общем, сами отстрелили себе ногу, использовав умный указатель не там, где это было нуно.
Это был лишь пример использования, чтобы показать что в случаях где нет необходимости контролировать время жизни объекта вручную, можно обойтись малой производительностью, но больше сконцентрироваться на логике
Sign up to leave a comment.

Articles