В C # каков наименьший способ хранения памяти в памяти для хранения строк базы данных? - PullRequest
0 голосов
/ 24 июня 2010

Я немного новичок в программировании на C # и мне нужен совет о том, как решить проблему.Мне нужно обработать десятки тысяч записей, хранящихся в базе данных SQL Server, и обработка должна быть максимально быстрой.

Чтобы максимизировать производительность, я извлекаю строки из базы данных в фоновом потоке, когдаприложение запускается, потому что оно должно ждать некоторого пользовательского ввода перед началом обработки.Такой подход экономит 20% времени всего процесса, но он очень ресурсоемкий с точки зрения использования памяти (процесс занимает 200 МБ ОЗУ, и я предполагаю, что строки базы данных содержат менее 10 МБ необработанных данных).

Я использую класс с членами, хранящими данные из столбцов базы данных, и использую ArrayList для хранения строк.

Есть ли другой подход для хранения данных в памяти, чтобы минимизировать потребление памяти?

Ответы [ 4 ]

1 голос
/ 24 июня 2010

Некоторые основные вещи, которые нужно проверить, не зная больше деталей о вашем приложении:

  • Вы храните в памяти только то, что вам нужно?
  • Вы создаете вещи в куче больших объектов ? Это скорее всего не будет собрано.
  • Можете ли вы обрабатывать данные партиями и сокращать результаты каждого пакета в другое промежуточное хранилище памяти / диска? По сути, можете ли вы использовать какую-либо форму уменьшения карты?
  • Используйте WinDBG для просмотра вашей кучи и просмотра корневых объектов. Это даст вам лучшее представление о том, что находится в 200 МБ.
1 голос
/ 24 июня 2010

Какие типы данных столбцов?

Если строк много, возможно, вы страдаете из-за этих строк. Строки .NET имеют UTF-16 (2 байта на символ) и (я думаю) имеют 16-18 байтов служебной информации на строку. Если вам действительно нужно сэкономить память, а данные представляют собой ASCII, вы можете рассмотреть возможность объединения нескольких строковых столбцов в байтовый массив с помощью Encoding.UTF8.

// Occupies 64 bytes of memory
string col1 = "Me", col2 = "You", col3 = "Us";

StringBuilder sb = new StringBuilder(col1);
// only works if you are sure the columns have no nulls
sb.Append('\0');
sb.Append(col2);
sb.Append('\0');
sb.Append(col3);

// Occupies 24 bytes of memory
byte[] array = Encoding.UTF8.GetBytes(sb.ToString());

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

1 голос
/ 24 июня 2010

Вам следует учитывать тот факт, что использование памяти, указанное в диспетчере задач, не является необходимым объемом памяти, используемой данными. Программа захватывает больше памяти, чем нужно в данный момент, чтобы иметь возможность хорошо масштабироваться. Если вы хотите узнать, сколько именно памяти используется, используйте профилировщик памяти.

0 голосов
/ 24 июня 2010

«Я использую класс с участниками» может быть вашей проблемой.Примитивные типы данных, такие как bool, int и т. Д., Должны примерно занимать то же пространство, что и в вашей БД.Но когда вы создаете новый экземпляр класса, дополнительные данные должны быть зарезервированы в куче.Теперь это не должно составлять 200 МБ при обработке только «десятков тысяч» строк, но вы можете вместо этого использовать тип значения (например, изменить класс на структуру).

Кроме того, если ваша база данныхсодержит строки примерно одинаковой длины. Вы можете использовать char-массивы для их хранения, чтобы «минимизировать потребляемую память».

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