我已经在这里工作了一些程序,现在已经有大量的字符串解析等等了。我被建议使用char数组来代替字符串,因为char数组更快。我理解为什么char数组很快,但字符串类型是什么让它变慢?它实现了什么数据结构,有没有办法让它像char数组一样快?
答案 0 :(得分:15)
最明显的区别是string
是不可变的。所以你不能修改它的一部分,需要在每次修改时创建一个全新的副本。
String本身有一个非常特殊的实现(它是一个可变大小的类),并且没有数组支持。我认为没有理由为什么字符串中char
的只读访问权限应该很慢。
因此,如果您想要更改字符串的一小部分,则需要使用StringBuilder
或char[]
。其中char[]
中的StringBuilder
更快,因为char[]
有额外的验证和间接。但是因为这是一个实现细节,所以自从我上次测试它以来它可能已经改变了。
只是对它进行基准测试,从.NET 4开始,设置StringBuilder
的成员的速度是char[]
的四倍。但是两者每秒可以完成超过200万次的任务,所以在实践中它很少发生。
从string
读取从StringBuilder
读取的速度略快(我的测试代码为25%)。另一方面,从char[]
读取比从char[]
读取要慢(因子为3)。
在所有基准测试中,我忽略了其他代码的开销。这意味着我的测试会低估差异。
我的结论是,虽然//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];
}
比替代方案更快,但只有你每秒超过数百兆字节才有意义。
{{1}}
(是的,我知道我的基准代码不是很好,但我认为它没有太大的区别。)
答案 1 :(得分:2)
char数组对字符串的优点是你可以在适当的位置改变字符数组;在C#字符串中是不可变的,因此任何更改都会在堆上创建一个具有更改版本字符串的新对象。在char数组中,您可以进行大量更改,而无需在堆上分配任何内容。