我在工作中使用一些需要进行大量字符串解析等操作的程序已有一个月了。 我被建议使用 char 数组,而不是 string,因为 char 数组更快。 我明白 char 数组更快的原因,但是 string 类型的缓慢是由于什么引起的呢? 它实现了什么样的数据结构,是否有任何方法使它像 char 数组一样快?
string
是不可变的。因此,您无法修改它的部分,并且需要在每次修改时创建全新的副本。char
应该不会很慢。StringBuilder
或 char[]
。在这两个选项中,char[]
是/曾经是更快的,因为 StringBuilder
具有额外的验证和间接性。但由于这是一项实现细节,自我上次测试以来可能已经发生了变化。char[]
的成员大约比 StringBuilder
快四倍。但是,两者都可以执行超过200百万个赋值操作,因此在实践中很少有影响。char[]
读取要稍快一些(对于我的测试代码而言增加了25%),而从 string
读取则略慢。另一方面,从 StringBuilder
读取则更慢(3倍),比从 char[]
读取要慢。char[]
比其他选项更快,但只有在每秒超过数百兆字节时才会有影响。//Write StringBuilder
StringBuilder sb = new StringBuilder();
sb.Length = 256;
for(int i=0; i<1000000000; i++)
{
int j = i&255;
sb[j] = 'A';
}
//Write char[]
char[] cs = new char[256];
for(int i=0; i<1000000000; i++)
{
int j = i&255;
cs[j] = 'A';
}
// Read string
string s = new String('A',256);
int sum = 0;
for(int i=0; i<1000000000; i++)
{
int j = i&255;
sum += s[j];
}
//Read char[]
char[] s = new String('A',256).ToCharArray();
int sum = 0;
for(int i=0; i<1000000000; i++)
{
int j = i&255;
sum += s[j];
}
//Read StringBuilder
StringBuilder s= new StringBuilder(new String('A',256));
int sum = 0;
for(int i=0; i<1000000000; i++)
{
int j = i&255;
sum += s[j];
}
(是的,我知道我的基准测试代码不是很好,但我认为这并没有太大的影响。)
使用字符数组而非字符串的优点在于你可以直接修改字符数组;在C#中,字符串是不可变的,因此任何更改都会在堆上创建一个新对象,其中包含字符串的更改版本。在字符数组中,你可以进行大量的更改而无需在堆上分配任何内容。