如何存储在内存中的字符串和char类型的.NET?(How are String and Char

2019-06-24 21:39发布

我需要存储一个语言代码字符串,如“恩”,这将总是包含2个字符。

它是更好地定义类型为“字符串”或“字符”?

private string languageCode;

VS

private char[] languageCode;

还是有另一种更好的选择吗?

如何这两个存储在内存中? 多少字节或比特将被分配给他们分配的值是什么时候?

Answer 1:

他们是如何保存

两个stringchar[]被存储在堆上-所以存储是相同的。 国内我会假设一个string简单地是一个盖char[]许多额外的代码,使其对您有用。

此外,如果你有很多重复串的,你可以利用实习 ,以减少这些字符串的内存占用。

更好的选择

我赞成字符串 - 它立即是更加明显的数据类型是什么,你打算如何使用它。 人们也更习惯使用字符串,以便维护不会受到影响。 您也将大大受益于已经为你做了所有的样板代码中获益。 微软也投入了大量的精力,以确保string类型不是性能猪。

分配大小

我不知道有多少是分配的,我相信字符串是在非常有效,他们只分配足够的存储Unicode字符 - 因为他们是不可变的是安全的做到这一点。 阵列也离不开一个新的阵列分配的空间大小,所以我又以为他们抢他们只需要什么。

一个.NET阵列的开销?

备择方案

根据您的信息,目前只有20个语言代码和性能是关键,你可以为了减少代表编码要求的尺寸声明自己的枚举:

enum LanguageCode : byte
{
    en = 0,
}

这将只需要1个字节,而不是为4+ 2个char (在阵列中),但它确实限制了可用的范围LanguageCode值的范围byte -这比足够大20项的更多。

你可以看到使用值类型的大小sizeof()运算符: sizeof(LanguageCode) 。 枚举不过是引擎盖下的基本类型,它们默认int ,但你可以在我的代码示例中所看到的,你可以通过“继承”的新型改变这种状况。



Answer 2:

简短的回答:使用字符串

长一点的回答:

private string languageCode;

AFAIK串被存储为字符的长度前缀阵列。 一个字符串对象被实例化在堆上保持这种生阵列。 但是,一个String对象是比简单数组它能够像比较,串联,串提取基本字符串操作更多,搜索等

private char[] languageCode;

将被存储为字符数组比如一个数组对象将在堆上创建,然后它会被用来管理你的角色。 但它仍然有其内部存储的相比字符串时所以有在存储器中没有明显的节约的长度属性。 虽然推测数组大于字符串简单的,并且可以具有从而提供较低的存储器脚印(这需要验证)较少的内部变量。

但OTOH你失去了这个字符数组执行字符串操作的能力。 即使是像字符串比较的业务现在成为累赘。 所以长话短说使用字符串!



Answer 3:

如何这两个存储在内存中? 多少字节或比特将被分配给他们分配的值是什么时候?

在.NET每个实例被存储如下:一个IntPtr用于类型标识符尺度的场; 多了一个用于锁定上的实例; 余数是向上舍入到一个实例字段数据IntPtr尺度的量。 因此,在32位的平台上每个实例占8个字节+场数据。

这适用于一个stringchar[] 这两种也存储数据作为一个IntPtr大小的整数,后跟实际数据的长度。 因此,一个两字符的string和一个两字符char[]在32位的平台上,将占据8 + 4 + 4 = 16个字节。

存储正好两个字符时要减少这个问题的唯一方法是将存储实际的字符,或含有该字符的结构,在一个场或一个数组。 所有这些将消耗的人物只有4个字节:

// Option 1
class MyClass
{
    char Char1, Char2;
}

// Option 2
class MyClass
{
    CharStruct chars;
}
...
struct CharStruct { public char Char1; public char Char2; }

MyClass最终将使用每个实例8个字节(32位机器上)加上4个字节字符。

// Option 3
class MyClass
{
    CharStruct[] chars;
}

这将使用8个字节用于MyClass的开销,加上4字节chars 参考 ,以及用于阵列的开销的12个字节,加上每个4个字节CharStruct在数组中。



Answer 4:

如果你想存储恰好2个字符,并最有效地做到这一点,使用结构:

struct Char2
{
 public char C1, C2;
}

使用这种结构一般不会造成新的堆分配。 它只是升迁现有的对象(由最小可能量)或消耗堆栈空间,这是非常便宜的。



Answer 5:

串确实有一个指针长度,即4个字节为一个32位的过程中,对于一个64位的处理8个字节的大小的额外开销。 但话又说回来,串回报不是char阵列提供了这么多。

如果应用程序使用许多短字符串,你并不需要经常使用它们的字符串的属性和方法,你可以的记忆可能是安全的几个字节。 但是,如果你想使用其中的任何一个字符串,你必须首先创建一个新的字符串实例。 我看不出这会帮助你安全的足够的内存是值得的麻烦。



文章来源: How are String and Char types stored in memory in .NET?