当前位置:首页 > 网络编程 > 软件语言 > .NET > StringBuilder提升字符串处理效率

StringBuilder提升字符串处理效率

点击次数:32 次 发布日期:2008-11-06 08:05:22 作者:源代码网
源代码网推荐
广告载入中

源代码网整理以下大家务必了解,System.String数据类型(或是说String对象)代表的是一种不变的字符串,也就是说,一旦您设定其值,您就不能更改它。如果您尝试要插入、删除或更改字符串的任何部分,唯一的方式就是去建立一个新的字符串。说得更专业点,每次字符串数据变更时,内存中该字符串原来的表示法就会被破坏掉,并建立内含新字符串数据的新表示法,此举会引发对内存的配置作业以及对内存的反配置作业。当然,这些作业都是在幕后完成的,因此真正的成本并不会立刻显现。配置与反配置内存会加重Common Language Runtime(CLR)里内存管理和内存回收的相关工作,所以绝对是要付出代价的,直接的影响,就是增了处理时间。这种情况在迅速地接连配置和反配置占有大块内存的字符串时尤其明显,就像在大量字符串串连时所发生的情况一样。虽然这种情形在单一用户环境里不会带来任何问题,但是在服务器的环境里使用时(比方说,在Web服务器上执行的ASP.NET® 应用程序中),却可能在效能与延展性上造成极为严重的问题。

源代码网整理以下 

源代码网整理以下以下面这一段程序代码而言(请参阅CH3_DemoForm017.vb之「使用String」按钮的Click事件处理例程),您知道在每一次的循环中,会发生多少次的字符串配置作业吗?答案是14。在此种写法中,「&」(或「+」)运算子会使得变量sXml所指向的字符串被破坏掉然后再重新建立。再次提醒您,字符串配置是很花时间的,而且随着字符串的增长,情况会越来越严重。这正是 .NET Framework为什么要提供StringBuilder类别的原因:

源代码网整理以下 

软件开发网 www.mscto.com

源代码网整理以下Dim nRep As Int32
Dim Reps As Int32 = Convert.ToInt32(numLoops.Value)

源代码网整理以下Dim Start, Finish As Double
Start = Microsoft.VisualBasic.DateAndTime.Timer

源代码网整理以下Dim sXml As String = ""

源代码网整理以下For nRep = 1 To Reps
    sXml &= "<订单 订单号码=""" _
         & nRep _
         & """ 订货日期=""" _
         & DateTime.Now.ToString() _
         & """ 客户编号=""" _
         & nRep _
         & """ 产品编号=""" _
         & nRep _
         & """ 产品说明=""" _
         & "此产品的 Id 是: " _
         & nRep _
         & """ 数量=""" _


         & nRep _
         & """/>"
Next nRep

源代码网整理以下sXml = "<订单 方法=""1"">" & sXml & "</订单>"

源代码网整理以下Finish = Microsoft.VisualBasic.DateAndTime.Timer
txtStringResult.Text = (Finish – Start).ToString 软件开发网 www.mscto.com

源代码网整理以下 

源代码网整理以下与System.String类别相较之下,System.Text.StringBuilder类别则会保留它自己的字符串缓冲区。在针对StringBuilder执行作业因而可能会改变字符串数据的长度时,StringBuilder会先检查缓冲区的大小是否足够容纳新的字符串数据。如果不够,则缓冲区的大小就会增加预先决定的数量。由于大幅降低内存配置操作的发生机率,因此自然能有效提升效能。

源代码网整理以下 

源代码网整理以下就以字符串串连作业而言,标准的串连方式会导致为每一项串连作业建立一个新字符串,但是StringBuilder却每次都使用相同的字符串缓冲区。基本上,当您只要修改字符串,但是不要建立新的字符串对象时,就应该使用System.Text命名空间中的StringBuilder类别。举例来说,当需要在循环中串连多个字符串时,使用StringBuilder类别将可具体提升效能。此外,StringBuilder类别还提供了非常有效率的Replace方法,它可以用来取代String.Replace。

源代码网整理以下 

源代码网整理以下基本上,StringBuilder方法在执行上会比标准串连方式优异的原因取决于几项因素,其中包括串连的数目、所要建置之字符串的大小、以及StringBuilder的缓冲区初始化参数是否设定得够好。请注意,在大多数的情况下,多估算一些缓冲区空间要比后来又不断加大来得更好。

源代码网整理以下 

源代码网整理以下以先前在循环中进行字符串串连作业的程序代码来说,如果使用StringBuilder将其改写如下(请参阅CH3_DemoForm017.vb之「使用StringBuilder」按钮的Click事件处理例程),将能够大幅提升执行速度,而且如果循环的数目愈多,提升的幅度愈明显:

源代码网整理以下 

源代码网整理以下Dim nRep As Int32
Dim Reps As Int32 = Convert.ToInt32(numLoops.Value)

源代码网整理以下Dim Start, Finish As Double
Start = Microsoft.VisualBasic.DateAndTime.Timer

源代码网整理以下Dim oSB As StringBuilder

源代码网整理以下" 确保StringBuilder的容量足以容纳最终的文字
oSB = New StringBuilder(Reps * 165)
oSB.Append("<订单 方法=""2"">")

源代码网整理以下For nRep = 1 To Reps
    oSB.Append("<订单 订单号码=""")
    oSB.Append(nRep)
    oSB.Append(""" 订货日期=""")
    oSB.Append(DateTime.Now.ToString())
    oSB.Append(""" 客户编号=""")
    oSB.Append(nRep)
    oSB.Append(""" 产品编号=""")
    oSB.Append(nRep)
    oSB.Append(""" 产品说明=""")
    oSB.Append("此产品的 Id 是: ")
    oSB.Append(nRep)
    oSB.Append(""" 数量=""")
    oSB.Append(nRep)
    oSB.Append("""/>")
Next nRep

源代码网整理以下oSB.Append("</订单>")

源代码网整理以下Finish = Microsoft.VisualBasic.DateAndTime.Timer
txtStringBuilderResult.Text = (Finish – Start).ToString

 
图表2
 

源代码网整理以下

使用StringBuilder类别
使用String类别
" 示范如何使用StringBuilder类别。

" StringBuilder是由System.Text命名空
" 间所提供,我们已在程序的开头处汇
" 入此命名空间(Imports System.Text)。
Dim sb As New StringBuilder( _
 "台湾微软技术社群暨" & _
 "最有价值专家 MVP")



sb.Insert(19, _
 "(Most Valuable Professional)")
sb.Remove(9, 6)
sb.Replace("技术社群", " Community ")
sb.AppendFormat( _
 "{0}年内{1}度当选。", "一", "两")

" 假设您要在单字 "MVP" 之后插入
" 一个句点,您必须先找到此单字,然
" 后再于该单字之后插入一个句点。欲
" 找到此单字,您必须使用IndexOf
" 加以搜寻,但是StringBuilder并未提
" 供此方法。因此,您务必使用ToString
" 方法来取得字符串,然后处理该字符串。
Dim intPos As Integer
intPos = sb.ToString.IndexOf("MVP")
If intPos > 0 Then
   " 插入逗点的位置就是您所搜寻到
   " 的位置再加上单字 "MVP" 的长
   " 度。
   sb.Insert( _
     intPos + "MVP".Length, ", ")
End If

txtResults.AppendText( _
 Environment.NewLine & _
 "StringBuilder 输出:" & _
 Environment.NewLine & _
 sb.ToString & Environment.NewLine)
" 同样的程序代码如果直接使用String物
" 件来处理,将如下所示。请注意到
" .NET Framework 需要去建立新字符串
" 的次数。StringBuilder 显然会比此种
" 操作来得更有效率。
Dim str As String = _
 "台湾微软技术社群暨" & _
 "最有价值专家 MVP"

str = str.Insert(19, _
 "(Most Valuable Professional)")
str = str.Remove(9, 6)
str = str.Replace( _
 "技术社群", " Community ")
str &= String.Format( _
 "{0}年内{1}度当选。", "一", "两")
Dim intPos As Integer
intPos = str.IndexOf("MVP")
If intPos > 0 Then
   str = str.Insert( _
     intPos + "MVP".Length, ", ")
End If

txtResults.AppendText( _
 Environment.NewLine & _


 "String 输出:" & _
 Environment.NewLine & _
 str & Environment.NewLine)

图表3String类别与StringBuilder类别使用比较
 
经由以上的说明,相信大家都对StringBuilder都已经抱持一个非常肯定的态度。

源代码网推荐

源代码网供稿.
网友评论 (0)
会员中心
网络编程
本站推荐
网络编程之精华