Как уменьшить объем памяти в .NET-приложениях с интенсивной интенсивностью? - программирование
Подтвердить что ты не робот

Как уменьшить объем памяти в .NET-приложениях с интенсивной интенсивностью?

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

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

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

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

4b9b3361

Ответ 1

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

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

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

UPDATE:

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

Ответ 2

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

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

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

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

Ответ 3

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

totearray:

string s = "whatever";
byte[] b = System.Text.Encoding.UTF8.GetBytes(s);

в строку:

string s = System.Text.Encoding.UTF8.GetString(b);

Ответ 4

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

Ответ 5

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