C#:占用更多内存的是什么?字符串或字节数组?

时间:2009-05-26 22:15:59

标签: c# .net string bytearray

C#:占用更多内存的是什么?字符串或字节?

假设我有一行显示“我的文本”,该行会以哪种形式占用更多内存,作为字节或字符串?

7 个答案:

答案 0 :(得分:12)

它取决于字节数组的字符编码。您可以将任何字符串转换为字节数组,但您必须选择编码;没有单一的标准或正确的编码。曾经被称为ASCII的东西在英语世界之外是没有用的。

在大多数编码中,“我的文本”长度为7个字节。但是抛出一些欧洲重音字符或日文字符,那些(如果它们可以表示)可能每个都超过一个或两个字节。在某些编码中,对于某些文本字符串,字节数组表示可能大于System.String使用的内部Unicode表示。

答案 1 :(得分:2)

成为Unicode并不意味着字符串每个字符占用的字节数超过一个字节,这只意味着它“可以”占用每个字符超过一个字节。

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

答案 2 :(得分:2)

  

什么占用更多内存?

所以你问的是内存中表示的大小。 .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字符之外的任何内容。

另一个略有不同的例子,欧洲人物“ä”。 UTF-8中的2个字节:

c3 a4

UTF-16中还有2个字节:

e4 00

ASCII不能代表此字符。

总结一下,消耗的内存取决于字符串中的实际数据以及用于表示它的编码

上述所有内容仅讨论原始数据的内存消耗,请注意,为了计算总内存消耗量,您还必须包含< strong>元数据,它是每个数组和字符串的一部分,如长度,在.net字符串的情况下,也是 null终结符(2值为“0”的附加字节。元数据的字节数是常量且相对较小,因此只要有大量非常小的文本,字符串和数组之间的任何差异都会很重要。

答案 3 :(得分:1)

两者都非常接近。只有一个真正的答案:

在您的框架/架构上对其进行分析。

答案 4 :(得分:0)

除非你有多个字符串副本,否则字节数组将占用更少的内存,在这种情况下,由于字符串表,字符串将占用更少的内存。

真正的问题是,它真的重要吗?将字符串用作字符串可以获得很多好处,而不是将其存储为字节数组。

我不知道具体细节,因为你的问题非常狭窄,但我闻到了过早的优化。

答案 5 :(得分:0)

字节数组。这将把您的文本存储为ASCII(每个字符1个字符)字符,而.NET字符串使用更大的Unicode。但请记住,.NET字符串可能更有用,而在大型应用程序中,差异可能不会产生巨大的差异。

(另请注意,如果您只在.NET字符串中使用ASCII字符,那么字符仍然只有1个字节)

答案 6 :(得分:0)

有一篇很好的博客文章here,它给出了字符串占用多少空间的公式,以及与StringBuilder&amp ;;实例分配