C# 串接字符串的最有效方法?
连接字符串最有效的方法是什么?最有效的方法是使用StringBuilder,如下所示:C# 串接字符串的最有效方法?,c#,.net,string,optimization,C#,.net,String,Optimization,连接字符串最有效的方法是什么?最有效的方法是使用StringBuilder,如下所示: StringBuilder sb = new StringBuilder(); sb.Append("string1"); sb.Append("string2"); ...etc... String strResult = sb.ToString(); @琼斯:绳子。如果你有一些小东西的话,海螺就可以了。但是,如果要连接兆字节的数据,您的程序可能会崩溃。使用StringBuilder.Append()方法
StringBuilder sb = new StringBuilder();
sb.Append("string1");
sb.Append("string2");
...etc...
String strResult = sb.ToString();
@琼斯:绳子。如果你有一些小东西的话,海螺就可以了。但是,如果要连接兆字节的数据,您的程序可能会崩溃。使用
StringBuilder.Append()
方法比使用+
操作符要好得多。但我发现,当执行1000次或更少的连接时,String.Join()
甚至比StringBuilder
更有效
StringBuilder sb = new StringBuilder();
sb.Append(someString);
String.Join
的唯一问题是必须用公共分隔符连接字符串
Edit:正如@ryanversaw指出的,您可以将分隔符设置为string.Empty
string key = String.Join("_", new String[]
{ "Customers_Contacts", customerID, database, SessionID });
对于两个字符串,您肯定不想使用StringBuilder。StringBuilder开销低于分配多个字符串的开销的阈值
String str1 = "sometext";
string str2 = "some other text";
string afterConcate = $"{str1}{str2}";
因此,对于超过2-3个字符串,请使用。否则,只需使用+运算符。来自:
经验法则
- 当连接三个或更少的动态字符串值时,请使用传统的字符串连接
- 当连接三个以上的动态字符串值时,请使用
StringBuilder
StringBuilder sb = new StringBuilder();
sb.Append(someString);
@
字符串文本或内联+运算符大多数情况下,
StringBuilder
是您的最佳选择,但如该帖子所示,您至少应该考虑每种情况。这取决于代码。
StringBuilder通常效率更高,但如果您只是将几个字符串串联在一起,并在一行中完成所有操作,那么代码优化可能会为您解决这一问题。考虑代码的外观也很重要:对于较大的集合,StringBuilder将使其更易于阅读,对于较小的集合,StringBuilder只会添加不必要的混乱。如果您在循环中操作,
StringBuilder
可能是一种方法;它为您节省了定期创建新字符串的开销。但是,在只运行一次的代码中,String.Concat
可能就可以了
然而,Rico Mariani(.NET optimization guru)在最后指出,在大多数情况下,他推荐.NET性能专家String.Format
,他在这个问题上做得非常好。这并不像人们想象的那么简单。基本建议如下:
如果您的模式看起来像:
x=f1(…)+f2(…)+f3(…)+f4(…)
这是一个海螺,它的活泼,StringBuilder可能不会有帮助
如果您的模式看起来像:
如果(…)x+=f1(…)
如果(…)x+=f2(…)
如果(…)x+=f3(…)
如果(…)x+=f4(…)
那么您可能需要StringBuilder
来自Eric Lippert,他在书中详细描述了在一行连接上执行的优化。:
与此相关的还有一些开销
创建StringBuilder对象,包括
在时间和记忆中。在一台有
快速内存,StringBuilder变得
如果你做了五件事,那就值得了
操作。根据经验,我
会说10个或更多的字符串操作
这是一个合理的开销
任何机器,哪怕是速度较慢的机器
因此,如果您信任MSDN,如果您必须执行10个以上的字符串操作/连接,请使用StringBuilder,否则使用“+”进行简单的字符串连接就可以了。这实际上取决于您的使用模式。 string.Join、string、Concat和string.Format之间的详细基准可以在这里找到:
(这实际上与我对问题的回答相同)有6种类型的字符串连接:
+
)符号string.Concat()
string.Join()
string.Format()
string.Append()
StringBuilder
string.Concat()
是最好的方法,如果单词大于1000,则应使用StringBuilder
有关更多信息,请查看此
string.Join()与string.Concat()的比较
这里的string.Concat方法相当于带有空分隔符的string.Join方法调用。追加一个空字符串很快,但不追加则更快,因此string.Concat方法在这里更为优越
同样重要的是要指出,如果要连接,应该使用
+
运算符
使用+运算符连接字符串文字或字符串常量时,编译器将创建单个字符串。没有发生运行时连接
System.String是不可变的。当我们修改一个字符串变量的值时,一个新的内存被分配给新的值,而之前的内存分配被释放。System.StringBuilder被设计为具有可变字符串的概念,其中可以执行各种操作,而无需为修改后的字符串分配单独的内存位置。除了其他答案之外,请记住这一点 capacity参数定义当前实例分配的内存中可以存储的最大字符数。将其值指定给属性。如果要存储在当前实例中的字符数超过此容量值,StringBuilder对象将分配额外的内存来存储这些字符 如果容量为零,则使用特定于实现的默认容量 反复附加到
String str1 = "sometext";
string str2 = "some other text";
string afterConcate = $"{str1}{str2}";
/// <summary>
/// Concatenate the strings in 'rg', none of which may be null, into a single String.
/// </summary>
public static unsafe String StringJoin(this String[] rg)
{
int i;
if (rg == null || (i = rg.Length) == 0)
return String.Empty;
if (i == 1)
return rg[0];
String s, t;
int cch = 0;
do
cch += rg[--i].Length;
while (i > 0);
if (cch == 0)
return String.Empty;
i = rg.Length;
fixed (Char* _p = (s = new String(default(Char), cch)))
{
Char* pDst = _p + cch;
do
if ((t = rg[--i]).Length > 0)
fixed (Char* pSrc = t)
memcpy(pDst -= t.Length, pSrc, (UIntPtr)(t.Length << 1));
while (pDst > _p);
}
return s;
}
[DllImport("MSVCR120_CLR0400", CallingConvention = CallingConvention.Cdecl)]
static extern unsafe void* memcpy(void* dest, void* src, UIntPtr cb);
List<string> lst= new List<string>();
for(int i=0; i<100000; i++){
...........
lst.Add(...);
}
return String.Join("", lst.ToArray());;