Re[5]: const string со счетчиком ссылок
От: andyp  
Дата: 28.02.20 10:47
Оценка: 5 (1) +4
Здравствуйте, Коваленко Дмитрий, Вы писали:


КД>В моем случае счетчик хранится в блоке с самими данными.


КД>Я этот shared_ptr поэтому и не люблю. Даже кушать не могу. То есть нигде не использую.


Если создаёшь shared_ptr через make_shared, то счётчик ссылок тоже вместе с данными будет. Я бы для начала в свой велосипед как раз shared_ptr и засунул. Посмотрел бы, что да как, а потом, если надо, то дальше бы оптимизировал.
Re[6]: const string со счетчиком ссылок
От: T4r4sB Россия  
Дата: 28.02.20 10:47
Оценка: +1
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Чтобы такое замутить на плюсах приходится городить шаред поинтер, подсчет ссылок.


Ну, исходная задача же такого не предполагает.

SVZ>А "грохать разом на выходе" я предложил, но Дмитрий не хочет


Не знаю, почему. Но в таких задачах ГЦ по-моему вообще ни разу не включится. И будет то же "разом на выходе"
Re[4]: const string со счетчиком ссылок
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 28.02.20 10:52
Оценка:
Здравствуйте, Igore, Вы писали:

КД>>Но я уже устал от своих велосипедов

I>Ну, можно еще старый gcc взять до С++11, где строки с cow реализованы

Лет 10 сидел на борланде, а последние 12 лет на VS.

Что-то навеяло — сижу за решеткой, в темнице сырой ...
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[6]: const string со счетчиком ссылок
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 28.02.20 10:58
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Атомарность присваивания ссылок в Яве позволяет очень здорово работать с иммутабельными объектами (теми же строками).

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

SVZ>Чтобы такое замутить на плюсах приходится городить шаред поинтер, подсчет ссылок.


SVZ>А "грохать разом на выходе" я предложил, но Дмитрий не хочет


У меня "на выходе" грохается словарь.

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

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

Собственно говоря, ответ мне тут уже подсказали — make_shared.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[6]: const string со счетчиком ссылок
От: EreTIk EreTIk's Box
Дата: 28.02.20 11:31
Оценка:
Здравствуйте, andyp, Вы писали:

КД>>В моем случае счетчик хранится в блоке с самими данными.


A>Если создаёшь shared_ptr через make_shared, то счётчик ссылок тоже вместе с данными будет.


С данными (байтами) самой строки?
Re[7]: const string со счетчиком ссылок
От: andyp  
Дата: 28.02.20 11:34
Оценка:
Здравствуйте, EreTIk, Вы писали:

ETI>С данными (байтами) самой строки?


Нет, конечно.
Re[8]: const string со счетчиком ссылок
От: EreTIk EreTIk's Box
Дата: 28.02.20 11:38
Оценка: +1
Здравствуйте, andyp, Вы писали:

ETI>>С данными (байтами) самой строки?


A>Нет, конечно.


Тогда это два выделения вместо трех, как я понял ТС хотел хранить счетчик с данными строки и получить одну аллокацию из кучи на формирование объекта строки.
Re[9]: const string со счетчиком ссылок
От: andyp  
Дата: 28.02.20 11:41
Оценка: +1
Здравствуйте, EreTIk, Вы писали:


ETI>Тогда это два выделения вместо трех, как я понял ТС хотел хранить счетчик с данными строки и получить одну аллокацию из кучи на формирование объекта строки.


Я отчасти поэтому и писал про "что да как". Если с++17, то можно shared_ptr<unsigned char[]> использовать, но тогда много чего придется делать заново руками.
Re[9]: const string со счетчиком ссылок
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 28.02.20 12:44
Оценка: 1 (1)
Здравствуйте, EreTIk, Вы писали:

ETI>Здравствуйте, andyp, Вы писали:


ETI>>>С данными (байтами) самой строки?


A>>Нет, конечно.


ETI>Тогда это два выделения вместо трех, как я понял ТС хотел хранить счетчик с данными строки и получить одну аллокацию из кучи на формирование объекта строки.


Да, точно. Я не сообразил, что std::wstring, хотя и хранится в блоке со счетчиком ссылок, сами данные будет хранить в отдельном блоке памяти

То есть, все таки с shared_ptr будет два блока вместо одного.

---
Я ради эксперимента перевел на std::shared_ptr<const std::wstring>.

Пришлось исправлять сравнения (нужно разыменовывать shared_ptr) и написать замену для std::less<std::shared_ptr<const std::wstring> — опять же ради разыменования.

  Работает не хуже — жрет под те же 600MB.
Это я решил потестить свою видеокарту и ютуб
https://youtu.be/uG_wXkFSueo

Пока смотрел как оно отрабатывает, увидел багу

UPD1. Я думаю, ютуба еще долго будет перекодировать видео под нормальное HD-разрешение. Там ~180 метров записалось.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Отредактировано 28.02.2020 12:47 DDDX . Предыдущая версия .
Re[7]: const string со счетчиком ссылок
От: qaz77  
Дата: 28.02.20 13:16
Оценка: +3
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Собственно говоря, ответ мне тут уже подсказали — make_shared.

std::make_shared<const std::string> будет оптимально (одним блоком) только для коротких строк, которые помещаются в SSO-буфер std::string'а.
Для длинных строк будет еще аллокация для буфера строки.

Если из интерфейса std::string кроме compare и c_str ничего не нужно, то можно сделать строчку оптимальнее.
К примеру, нет необходимости хранить size и capacity и счетчик всегда будет в одном блоке с символами строки.

Я решал похожую задачу с константными строками и не стал связываться с подсчетом ссылок.
Сделал пул памяти поверх кучи Windows (HeapCreate, HeapAlloc, HeapDestroy) с выделением от 64K и больше.
Нуль-терминированные строки "ложились" в блоках одна за другой.
При создании строки наружу выдавался const char*, удаление отдельной строки не предусматривалось.
Когда большой объект (вроде DOM — в моем случае), владеющий всеми этими строками, становился не нужен, то просто удалялся весь пул (HeapDestroy).

Все получается предельно компактно, шустро работает и потокобезопасно в пределах времени жизни большого объекта.
Реализация занимает 100 строчек, включая ассерты.
Re[7]: const string со счетчиком ссылок
От: удусекшл  
Дата: 28.02.20 14:07
Оценка: +2
Здравствуйте, EreTIk, Вы писали:

КД>>>В моем случае счетчик хранится в блоке с самими данными.


A>>Если создаёшь shared_ptr через make_shared, то счётчик ссылок тоже вместе с данными будет.


ETI>С данными (байтами) самой строки?


Если строки короткие, то доп выделения не будет
Re: const string со счетчиком ссылок
От: ononim  
Дата: 28.02.20 15:11
Оценка:
КД>В STL что-то подобное для константных строк есть?
std::shared_ptr<std::string> ?
можно еще так: strict SharedStringPool : std::set<std::shared_ptr<std::string>, shared_str_compare > { std::shared_ptr<std::string> GetPooledString(const std::string&); }
Как много веселых ребят, и все делают велосипед...
Re: const string со счетчиком ссылок
От: ArtDenis Россия  
Дата: 28.02.20 15:37
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>В STL что-то подобное для константных строк есть?


Использую std::shared_ptr<const std::[w]string> + небольшой лисапед со словарём для абсолютно тех же целей.
Делалось это ещё до std::string_view. Если бы делал сейчас, то наружу торчал бы только std::string_view
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[2]: const string со счетчиком ссылок
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 28.02.20 15:56
Оценка:
Здравствуйте, ArtDenis, Вы писали:

AD>Делалось это ещё до std::string_view. Если бы делал сейчас, то наружу торчал бы только std::string_view


string_view — это все таки штука для доступа/представления, а не для хранения. Насколько я понимаю.

Тут, кстати, лет так двенадцать или пятнадцать кто-то поделился идей аналогичной string_view и я ей у себя воплотил в виде t_const_[w]str_box.

Теперь вот надо будет этот велосипед приводить к виду string_view, а потом выкидывать.

---
Штука классная, да. После неё забавно смотреть как мечутся между const char* и классами строк
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[3]: const string со счетчиком ссылок
От: ArtDenis Россия  
Дата: 28.02.20 16:14
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>string_view — это все таки штука для доступа/представления, а не для хранения. Насколько я понимаю.


Если твои данные гарантированно не меняются, наружу можно выдавать std::string_view. А как оно внутри хранится (в данном случае это std::shared_ptr<const std::string>) это уже не важно.

Я бы сейчас вот так сделал (псевдокод):
std::string_view ConstStrDict::get(std::string_view str)
{
    auto it = dict_.find(str);
    if (it == dict_.end())
        it = dict_.insert(std::pair { str, std::make_shared<std::string>(str) });
    return *it->second;
}

Сейчас же выдаётся наружу std::shared_ptr<const std::string>. Просто лень переписывать
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Отредактировано 28.02.2020 19:32 ArtDenis . Предыдущая версия .
Re[4]: const string со счетчиком ссылок
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 28.02.20 16:50
Оценка:
Здравствуйте, ArtDenis, Вы писали:

КД>>string_view — это все таки штука для доступа/представления, а не для хранения. Насколько я понимаю.


AD>Если твои гарантированно данные не меняются, наружу можно выдавать std::string_view. А как оно внутри хранится (в данном случае это std::shared_ptr<const std::string>) это уже не важно.


Я тут выше писал
Автор: Коваленко Дмитрий
Дата: 28.02.20
, что словарь хранится только в процессе формирования задач.

Потом словарь грохается, но строки продолжают жить своей жизнью и постепенно изничтожаются.

Если в задачах удерживать словарь, то он будет удерживать все строки до завершения последней задачи. А мне такое не надо.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[5]: const string со счетчиком ссылок
От: ArtDenis Россия  
Дата: 28.02.20 19:36
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:


КД>Я тут выше писал
Автор: Коваленко Дмитрий
Дата: 28.02.20
, что словарь хранится только в процессе формирования задач.

КД>Потом словарь грохается, но строки продолжают жить своей жизнью и постепенно изничтожаются.
КД>Если в задачах удерживать словарь, то он будет удерживать все строки до завершения последней задачи. А мне такое не надо.

Да, всё зависит от задачи. Универсального решения нету.

Кстати, можно периодически уничтожать в словаре элементы, на которые нету ссылок. Тогда не будут накапливаться уже не используемые строки. Но тогда наружу надо выдавать std::shared_ptr<std::string>
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Отредактировано 28.02.2020 19:44 ArtDenis . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.