C #: Что занимает больше памяти? Строка или байт-массив? - PullRequest
8 голосов
/ 27 мая 2009

C #: Что занимает больше памяти? Строка или байты?

Допустим, у меня есть строка с надписью «Мой текст», в какой форме эта строка будет использовать больше памяти в виде байта или строки?

Ответы [ 7 ]

12 голосов
/ 27 мая 2009

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

В большинстве кодировок «Мой текст» будет иметь длину 7 байт. Но добавьте некоторые символы с европейским акцентом или японские символы, и они (если они вообще могут быть представлены) могут содержать более одного или двух байтов каждый. В некоторых кодировках с некоторыми текстовыми строками представление массива байтов может быть больше, чем внутреннее представление Unicode, используемое System.String.

2 голосов
/ 30 октября 2012

Что занимает больше памяти?

Итак, вы спрашиваете о размере представления в памяти . .net использует UTF-16 для строк, что означает, что ваш пример будет представлен 14 байтами, как видно из этого шестнадцатеричного дампа (UTF-16LE):

4d 00 79 00 20 00 54 00  65 00 78 00 74 00

Размер байтового массива будет зависеть от кодировки , которую вы используете для представления текста. Если вы используете UTF-16 , как это

Encoding.Unicode.GetBytes(string)

вы, очевидно, получаете те же 14 байтов. Если вы используете UTF-8 вместо:

Encoding.UTF8.GetBytes(string)

вы получите массив из 7 байтов:

4d 79 20 54 65 78 74

Это тот же размер (и то же представление), что и ASCII , поскольку в вашем примере используются только те символы, которые доступны в кодировке ASCII. Все эти символы, по определению, одинаковы в UTF-8.

Теперь, если вместо этого вы используете не-ASCII-символов , скажем, японское «日», для кодировки UTF-8 потребуется 3 байта:

e6 97 a5

UTF-16 потребуется только 2 байта:

e5 65

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

Еще один немного другой пример, европейский символ "ä". 2 байта в UTF-8:

c3 a4

Также 2 байта в UTF-16:

e4 00

ASCII не может представлять этот символ.

Подводя итог, используемая память зависит от фактических данных в ваших строках и от того, какую кодировку вы используете для их представления .

Все вышесказанное говорит о потреблении памяти только для необработанных данных , обратите внимание, что для расчета общего потребления памяти вам также необходимо включить метаданные , которые являются частью каждого массива и строки, например, длина , а в случае строк .net также нулевой терминатор (2 дополнительных байта со значением '0'). Количество байтов для метаданных является постоянным и относительно небольшим, поэтому любая разница между строкой и массивом будет иметь значение только при наличии тонны очень маленьких текстов.

2 голосов
/ 27 мая 2009

Наличие Unicode не означает, что строка будет занимать более одного байта на символ, это просто означает, что она «может» занимать более одного байта на символ.

http://www.joelonsoftware.com/articles/Unicode.html

1 голос
/ 27 мая 2009

Оба довольно близки. Только один реальный ответ:

Профилируйте его в своей структуре / архитектуре.

0 голосов
/ 27 мая 2009

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

0 голосов
/ 27 мая 2009

Массив байтов. Это сохранит ваш текст как символы ASCII (1 байт на символ), тогда как строка .NET использует Unicode, которые больше. Однако помните, что строки .NET, вероятно, более полезны, и в больших приложениях разница, вероятно, не будет иметь большого значения.

(обратите внимание также, что если вы просто используете символы ASCII в вашей строке .NET, то символы по-прежнему будут содержать только 1 байт)

0 голосов
/ 27 мая 2009

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

Но настоящие вопросы - это действительно имеет значение? Существует много преимуществ использования строки в виде строки, а не ее хранения в виде массива байтов.

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

...