C# .NET探查器显示有关字符串处理的冲突
由于性能问题,我一直在分析我的应用程序中的线程冲突,在一个包含很多字符串的类中发现了很多冲突。我的代码如下所示:C# .NET探查器显示有关字符串处理的冲突,c#,.net,multithreading,locking,stringbuilder,C#,.net,Multithreading,Locking,Stringbuilder,由于性能问题,我一直在分析我的应用程序中的线程冲突,在一个包含很多字符串的类中发现了很多冲突。我的代码如下所示: var builder = new StringBuilder(); //some contentions here (WHY?) var copy = string.Copy(existingString); //some here (understandable) builder.Append(Escape(copy)); //a LOT of contentions her
var builder = new StringBuilder(); //some contentions here (WHY?)
var copy = string.Copy(existingString); //some here (understandable)
builder.Append(Escape(copy)); //a LOT of contentions here (most of them on Append(), some on Escape())
转义(string)如下所示(所有私有变量都是私有的只读静态字符串,内联定义)
我的问题是,为什么在我只创建
StringBuilder
的新实例、对该StringBuilder
调用Append
或对显式复制的字符串调用stringInstance.Replace
的行上会出现冲突。所有这些都应该是局部变量,所以不应该有锁争用,对吗?我遗漏了什么?这里很可能存在GC堆锁争用。这是非常重要的,提供一个体面的估计能力的StringBuilder,否则你会死一千针刺伤。您应该看到,软页面错误的高比率是一种副作用。通过迁移到.NET4并使用ServerGC进一步改进结果。我现在切换到4.0,这没有多大区别。我还指定了stringbuilder的容量,这很有帮助。将尝试使用服务器GC。使用服务器GC并避免创建新的StringBuilder(而是重用同一个)似乎有助于解决此问题。现在争议最多的是克隆字典:var d=新字典(oldDic);这是一个相关的问题吗?GC堆锁?@HansPassant我认为GC问题是这里的问题。你能把它写下来回答我吗?
private static string Escape(string str)
{
return str
.Replace(_backSlash, _escapedBackSlash) //double backslash
.Replace(_quote, _escapedQuote) //quote
.Replace(_newline, string.Empty) //line break
.Replace(_return, string.Empty) //carriage return
.Replace(_tab, string.Empty) //tab
.Replace(_verticalTab, string.Empty) //vertical tab (i know, right?)
.Replace(_dataLink, string.Empty); //data link char escape
}
}