Как уменьшить объем памяти в приложениях, интенсивно работающих со строками .NET? - PullRequest
17 голосов
/ 09 марта 2012

У меня есть приложение, в памяти которого ~ 1000000 строк по соображениям производительности .Мое приложение использует ~ 200 МБ ОЗУ.

Я хочу уменьшить объем памяти, используемой строками.

Я знаю .NET представляет строки в кодировке UTF-16 (2 байта на символ),Большинство строк в моем приложении содержат чисто английские символы, поэтому их хранение в кодировке UTF-8 будет в 2 раза эффективнее, чем в UTF-16.

Есть ли способ сохранить строку в памяти в кодировке UTF-8?разрешая стандартные строковые функции?(Мои потребности, в основном, IndexOf с StringComparison.OrdinalIgnoreCase).

Ответы [ 5 ]

11 голосов
/ 09 марта 2012

К сожалению, вы не можете изменить .Net внутреннее представление строки. Я предполагаю, что CLR оптимизирован для многобайтовых строк.

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

Тем не менее, взгляните на некоторые соображения здесь . Если бы я был вами, однажды установив, что прироста памяти вам будет достаточно, попробуйте написать свой собственный «строковый» класс, который использует кодировку ASCII. Это, вероятно, будет достаточно.

UPDATE:

Подробнее о деньгах, вы должны проверить этот пост, " Памяти и строк ", автор легенды StackOverflow Джон Скит, который решает проблему, с которой вы сталкиваетесь. Извините, я не упомянул об этом сразу, мне потребовалось некоторое время, чтобы найти точный пост от Джона.

4 голосов
/ 09 марта 2012

Есть ли способ сохранить строку в памяти в кодировке UTF-8, допуская при этом стандартные функции string>?(Мои потребности включают в себя главным образом IndexOf с StringComparison.OrdinalIgnoreCase).

Вы можете хранить в виде байтового массива и предоставлять собственную реализацию IndexOf (поскольку преобразование обратно в строку для IndexOf, скорее всего, сильно снизит производительность).Для этого используйте функции System.Text.Encoding (лучше всего было бы сделать шаг компоновки, чтобы преобразовать в байты, а затем прочитать байтовые массивы с диска - только преобразовать обратно в строку для отображения, если необходимо).

Вы можете хранить их в библиотеке C / C ++, позволяя использовать однобайтовые строки.Вы, вероятно, не захотите их маршалировать обратно, но вы могли бы просто маршалировать результаты (я полагаю, что здесь идет какой-то поиск) без особого успеха.C ++ / CLI может сделать это проще (имея возможность писать код поиска на C ++ / CLI, но строку «database» на C ++).

Или вы можете вернуться к исходным проблемам с производительностью, которые требуют всеСтроки в памяти.Встроенная база данных, индексация и т. Д. Могут как ускорить процесс , так и , уменьшить использование памяти и быть более удобными для обслуживания.

2 голосов
/ 10 марта 2012

попробуйте использовать in-memory-DB для «хранения» и SQL для взаимодействия с данными ... Например, SQLite может быть развернут как часть вашего приложения (состоит всего из 1-2 DLL, которые могут быть размещены в та же папка, что и ваше приложение) ...

2 голосов
/ 09 марта 2012

Что делать, если вы храните его как байтовый массив?Просто восстановите строку, когда вам нужно будет выполнить некоторые операции с ней.Я бы сделал класс для установки и получения строк, которые внутренне сохраняют его как байтовые массивы.

0 голосов
/ 09 марта 2012

Что если вы создадите свой собственный класс строки UTF-8 (UTF8String?) И предоставите неявное приведение к String?Вы будете жертвовать некоторой скоростью ради памяти, но это может быть то, что вы ищете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...