.NET Strings vs. Streams - Профиль и характеристики памяти

Мне нужно извлечь большие текстовые строки Unicode (например, 200 МБ) из базы данных (nvarchar) и сохранить в памяти для обработки. т.е. мне нужен произвольный доступ ко всем частям строк.

Если посмотреть на это с точки зрения строго памяти, каковы плюсы и минусы использования System.IO.MemoryStream по сравнению с System.String в качестве моего представления в памяти.

Вот некоторые факторы, которые я пытаюсь исследовать:

  • Как эти объекты действуют в [гипотетической] сильно фрагментированной среде с низким объемом памяти
  • Неизменность
  • Фактический размер в памяти (если поток - UTF8, есть ли у нас почти размер уменьшен вдвое)
  • Есть ли еще один объект, о котором я не думал?

Я ищу ясности и советов по этим вопросам, а также любых других соображений памяти, о которых я не думал?

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

какие-нибудь хорошие образцы с исходным кодом ??

Kiquenet 29.12.2010 17:57
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
7
1
2 187
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Looking at this from strictly memory centric point of view, what are the pro’s and con’s of using a System.IO.MemoryStream versus a System.String as my in memory representation.

Some factors I am trying to research are:

  • How these objects act in a [hypothetical] highly fragmented low memory environment

IMO, MemoryStream полезен только тогда, когда кодировка тривиальна (например, ASCII, ISO-8859-X и т. д.). Если кодировка UTF-8 а также, у вас есть символы, отличные от ASCII, тогда обработка станет более сложной. Конечно, MemoryStream почти наверняка будет потреблять меньше памяти, но в остальном особой разницы нет. Под капотом MemoryStream использует массив байтов, который также необходимо выделить в непрерывном блоке памяти.

  • Actual size in memory (if stream is UTF8, have we nearly halved size)

Правильно, с чисто символами ASCII, MemoryStream будет потреблять половину того, что потребляет эквивалентная строка.

  • Is there another object I have not thought about?
List<byte> // has a nicer interface for processing

Как строки хранятся в базе данных? варчар или нварчар?

С уважением,

Андреас

Спасибо Андреасу, строки выходят из базы данных как nvarchar.

nick_alot 29.12.2008 12:41

Привет, Андреас. После некоторого дальнейшего чтения в MSDN я прочитал, что MemoryStream, созданный с помощью конструктора по умолчанию, имеет изменяемый размер, поэтому это означает, что он не требует непрерывного блока памяти. Это справедливое предположение?

nick_alot 29.12.2008 12:58

см .: msdn.microsoft.com/en-us/library/…

nick_alot 29.12.2008 12:58

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

user49572 29.12.2008 12:59

Теперь я пытаюсь перейти от DB -> IDataReader -> StreamWriter -> MemoryStream. Кажется, это работает, избегая любого System.String в памяти

nick_alot 29.12.2008 13:03

Нет, изменение размера MemoryStream внутренне просто выделит массив байтов, вдвое превышающий текущий размер, а затем скопирует содержимое старого массива в новый массив, так что после изменения размера блок останется непрерывным. Вы можете использовать .NET Reflector для просмотра MemoryStream.SetLength.

user49572 29.12.2008 13:12

Да, возможно, лучше всего использовать DataReader. Я предполагаю, что вы читаете строку БД в нескольких блоках и конвертируете их в UTF-8, прежде чем записывать их в MemoryStream, верно? Если это так, то вызов MemoryStream.SetSize раньше позволит избежать дополнительных выделений и копирования.

user49572 29.12.2008 13:40

Память строки и потока довольно несущественна. Строки - это utf-16, поэтому май будет небольшим числом задействованных, но из-за задействованных томов вам, вероятно, будет лучше записывать данные в рабочий файл.

Чтобы прочитать данные из базы данных, используйте методы потоковой передачи; то есть использовать IDataReader (ExecuteReader) в последовательном режиме и читать блоки байтов / символов. Не пытайтесь прочитать всю колонку.

Кроме того, с SQL Server 2008 вам не захочется смотреть на тип файлового потока.

Примеры:

Другие вопросы по теме