Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>В одной небольшой задачке потребовалось загрузить снаружи некий набор строк, а потом его мутузить разными способами.
КД>Я на это дело посмотрел и вспомнил про свой велосипед — класс для константных строк с использованием счетчика ссылок. КД>Прикрутил этот класс к этой программе, реализовал создание новых экземпляров через словарь строк.
КД>--- КД>В STL что-то подобное для константных строк есть? string_view, может для твоего сценария и не подойдет
Здравствуйте, Igore, Вы писали:
I>Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>>В одной небольшой задачке потребовалось загрузить снаружи некий набор строк, а потом его мутузить разными способами.
КД>>Я на это дело посмотрел и вспомнил про свой велосипед — класс для константных строк с использованием счетчика ссылок. КД>>Прикрутил этот класс к этой программе, реализовал создание новых экземпляров через словарь строк.
КД>>--- КД>>В STL что-то подобное для константных строк есть? I>string_view, может для твоего сценария и не подойдет
Не. Не то.
Тут строки создаются толпой, но потом они живут своей жизнью. Постепенно они изничтожаются.
Можно было, конечно, создать словарь std::wstring, потом его юзать указатели на его элементы. Но это не то.
Еще можно было в "shared_ptr" строки засунуть — но это два раза память выделяться будет (здесь я не уверен, не пробовал, только сейчас об этом подумал).
---
Хотелось нормальный read-only класс строки, которая при присваивании будет увеличивать счетчик ссылок у разделяемых данных.
Мой велосипед так и делает.
Но я уже устал от своих велосипедов
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Еще можно было в "shared_ptr" строки засунуть — но это два раза память выделяться будет (здесь я не уверен, не пробовал, только сейчас об этом подумал). КД>Хотелось нормальный read-only класс строки, которая при присваивании будет увеличивать счетчик ссылок у разделяемых данных.
shared_ptr<const std::string> как раз должен подойти, дополнительная память будет выделяться только под счетчики ссылок, а строки будут неизменяемые.
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>В одной небольшой задачке потребовалось загрузить снаружи некий набор строк, а потом его мутузить разными способами.
КД>VS2019.
КД>Я сначала замутил её на базе std::wstring.
КД>Программулина выжрала почти 4GB, что было на грани фола для 32-битного процесса.
А можно саму задачу? Мне кажется, у тебя ошибка в том, что ты для внутренних операций копировал строки, вместо перекидывания ссылок на них.
КД>Тут строки создаются толпой, но потом они живут своей жизнью. Постепенно они изничтожаются.
А это важно, что они уничтожаются постепенно, а не в конце все разом?
Здравствуйте, Chorkov, Вы писали:
КД>>Но я уже устал от своих велосипедов
C>А что за операции предполагается проволить со строками, кроме сравнения на равенство?
В этой конкретной задаче:
1. Сравнение. По факту, используется только оператор <. В словаре строк.
2. Получение самой строки, для формирования текстов запросов к базе.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, T4r4sB, Вы писали:
КД>>В одной небольшой задачке потребовалось загрузить снаружи некий набор строк, а потом его мутузить разными способами.
КД>>VS2019.
КД>>Я сначала замутил её на базе std::wstring.
КД>>Программулина выжрала почти 4GB, что было на грани фола для 32-битного процесса.
TB>А можно саму задачу? Мне кажется, у тебя ошибка в том, что ты для внутренних операций копировал строки, вместо перекидывания ссылок на них.
Это часть тестовой системы.
Сначала формируются тестовые данные, которые потом рассовываются по (параллельно выполняемым) подзадачам.
КД>>Тут строки создаются толпой, но потом они живут своей жизнью. Постепенно они изничтожаются.
TB>А это важно, что они уничтожаются постепенно, а не в конце все разом?
По мере того как подзадачи отрабатывают, память освобождается.
Этих подзадач ~10тыщ.
А общая толпа, в рамках которой они работают — за 700 тысяч.
Удерживать словарь до завершения работы последней подзадачи не очень разумно. Особенно на 32х битах.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Сначала формируются тестовые данные, которые потом рассовываются по (параллельно выполняемым) подзадачам.
Всё равно не вижу причин рассылать копии строк, а не ссылки на них.
КД>Удерживать словарь до завершения работы последней подзадачи не очень разумно. Особенно на 32х битах.
Здравствуйте, XuMuK, Вы писали:
КД>>Еще можно было в "shared_ptr" строки засунуть — но это два раза память выделяться будет (здесь я не уверен, не пробовал, только сейчас об этом подумал). КД>>Хотелось нормальный read-only класс строки, которая при присваивании будет увеличивать счетчик ссылок у разделяемых данных. XMK>shared_ptr<const std::string> как раз должен подойти, дополнительная память будет выделяться только под счетчики ссылок, а строки будут неизменяемые.
Да, я тоже про это подумал. Но — вот это вот дополнительное выделение памяти напрягает.
В моем случае счетчик хранится в блоке с самими данными.
Я этот shared_ptr поэтому и не люблю. Даже кушать не могу. То есть нигде не использую.
----
Вообще этот мой велосипед (const_string) относительно хорошо продуман, поскольку он может представлять как строки из динамической памяти, так и статические строки
----
А вместо string_view у меня юзается другой велосипед — const_str_box.
Кривоватые, конечно. Но .... делать
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Здравствуйте, Chorkov, Вы писали:
КД>>>Но я уже устал от своих велосипедов
C>>А что за операции предполагается проволить со строками, кроме сравнения на равенство?
КД>В этой конкретной задаче:
КД>1. Сравнение. По факту, используется только оператор <. В словаре строк. КД>2. Получение самой строки, для формирования текстов запросов к базе.
Надеюсь запросы на поиск полного совпадения строк, а не подстроки в строке?
Тогда, стоит поменять структуру базы: дабавит таблицу уникальных идентификаторов, и далее пользоваться только их номерами (ссылками на эту таблицу).
На стороне C++ строк вообще не будет.
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>В одной небольшой задачке потребовалось загрузить снаружи некий набор строк, а потом его мутузить разными способами. КД>Программа стала жрать 600MB максимум.
КД>В STL что-то подобное для константных строк есть?
Гм, а сколько всего строк и какой их размер?
Может не стоит связываться с СТЛ?
Для таких сценариев хорошо работает переход от отдельных строк к объекту "коллекция строк". Все строки лежат в одном блоке памяти.
Доступ к строке — по индексу.
Хочешь — возвращай указатель на 0-terminated строку, хочешь — самописный аналог string_view (обертка над парой указателей или указатель+длина).
Еще в ДОСовские времена использовали такую штуку.
Удаление из коллекции в этом случае не очень эффективно, но может оно и не нужно? На выходе разом всю память освободишь.
_____________________
С уважением,
Stanislav V. Zudin
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>VS2019.
КД>Прикрутил этот класс к этой программе, реализовал создание новых экземпляров через словарь строк.
КД>В STL что-то подобное для константных строк есть?
Здравствуйте, Stanislav V. Zudin, Вы писали:
SVZ>Гм, а сколько всего строк и какой их размер?
Я их не считал — много наверное.
SVZ>Может не стоит связываться с СТЛ? SVZ>Для таких сценариев хорошо работает переход от отдельных строк к объекту "коллекция строк". Все строки лежат в одном блоке памяти. SVZ>Доступ к строке — по индексу. SVZ>Хочешь — возвращай указатель на 0-terminated строку, хочешь — самописный аналог string_view (обертка над парой указателей или указатель+длина). SVZ>Еще в ДОСовские времена использовали такую штуку.
SVZ>Удаление из коллекции в этом случае не очень эффективно, но может оно и не нужно? На выходе разом всю память освободишь.
Словарь строк формируется в процессе формирования подзадач. И эти подзадачи сразу уезжают на выполнение.
Когда все подзадачи сформированы, словарь грохается.
Но строки остаются — в тех подзадачах которые выполняются или еще не были выполнены.
Строки, которые были привязаны к завершенным подзадачам, но удерживались словарем, будут удалены вместе со словарем — он обнуляет их счетчик ссылок.
Подзадачи про словарь вообще ничего не знают. Им дали наборы строк, они с ними и работают.
-----------------
В Борландовская STL была std::string со счетчиком ссылок.
А в студии — каждая std::string хранит копию данных.
В этом и печаль.
Мне так кажется, что в STL нужна (константная) строка со счетчиком ссылок. Хотя, с другой стороны, вроде как std::shared_ptr<const string> проблему решает.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, EreTIk, Вы писали:
КД>>Прикрутил этот класс к этой программе, реализовал создание новых экземпляров через словарь строк.
КД>>В STL что-то подобное для константных строк есть?
ETI>Может из ATL подойдет?
То есть в STL такого нет
Стороннее мне не надо.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
КД>Словарь строк формируется в процессе формирования подзадач. И эти подзадачи сразу уезжают на выполнение. КД>Когда все подзадачи сформированы, словарь грохается. КД>Но строки остаются — в тех подзадачах которые выполняются или еще не были выполнены.
Между подзадачами много дубликатов?
Если так, то шаред поинтер нормальное решение.
КД>В Борландовская STL была std::string со счетчиком ссылок. КД>А в студии — каждая std::string хранит копию данных.
Стандарт-с, однако.
КД>Мне так кажется, что в STL нужна (константная) строка со счетчиком ссылок.
Красиво, как в Яве, всё равно не получится. Для этого GC нужен.
_____________________
С уважением,
Stanislav V. Zudin
Здравствуйте, Stanislav V. Zudin, Вы писали:
КД>>Словарь строк формируется в процессе формирования подзадач. И эти подзадачи сразу уезжают на выполнение. КД>>Когда все подзадачи сформированы, словарь грохается. КД>>Но строки остаются — в тех подзадачах которые выполняются или еще не были выполнены.
SVZ>Между подзадачами много дубликатов?
Как минимум есть x3. Тестируются строки в прямом порядке, в обратном порядку и random
А так, отдельные строки могут в большем количестве подзадач использоваться — я не вникал.
SVZ>Если так, то шаред поинтер нормальное решение.
+1 один блок под счетчик...
SVZ>Красиво, как в Яве, всё равно не получится. Для этого GC нужен.
С явой не работал. Но, в свете всей это ..., понял почему в C# строки константные
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Здравствуйте, T4r4sB, Вы писали:
SVZ>>Красиво, как в Яве, всё равно не получится. Для этого GC нужен.
TB>Чтоб было "как в GC", надо просто все строки хранить в одном месте а потом грохать разом на выходе.
Не, я немного про другое.
Атомарность присваивания ссылок в Яве позволяет очень здорово работать с иммутабельными объектами (теми же строками).
На многопоточных задачах можно не заморачиваться синхронизацией — если потребовалось модифицировать объекто, то тупо заменяем старый объект новым. GC потом приберет освободившихся.
Чтобы такое замутить на плюсах приходится городить шаред поинтер, подсчет ссылок.
А "грохать разом на выходе" я предложил, но Дмитрий не хочет
_____________________
С уважением,
Stanislav V. Zudin
Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>Тут строки создаются толпой, но потом они живут своей жизнью. Постепенно они изничтожаются.
КД>Можно было, конечно, создать словарь std::wstring, потом его юзать указатели на его элементы. Но это не то.
КД>Еще можно было в "shared_ptr" строки засунуть — но это два раза память выделяться будет (здесь я не уверен, не пробовал, только сейчас об этом подумал).
КД>--- КД>Хотелось нормальный read-only класс строки, которая при присваивании будет увеличивать счетчик ссылок у разделяемых данных.
КД>Мой велосипед так и делает.
КД>Но я уже устал от своих велосипедов
Ну, можно еще старый gcc взять до С++11, где строки с cow реализованы