VB.NET中字符串中的字符替换

Tim*_*Tim 6 vb.net string character-replacement

我能以多快的速度替换字符串中的字符?

因此,这个问题的背景是:我们有几个应用程序通过套接字相互通信并与客户端的应用程序通信.这些套接字消息包含不可打印的字符(例如chr(0)),需要用预定的字符串替换(例如"{Nul}"},因为套接字消息保存在日志文件中.每条日志消息都需要替换字符.

现在我从这个MSDN链接开始阅读这个小冒险,我从这个网站的另一篇文章中找到了这个链接.

我们当天使用的当前方法......在一天开始时...使用StringBuilder来检查所有可能的替换,例如......

    Public Function ReplaceSB(ByVal p_Message As String) As String
      Dim sb As New System.Text.StringBuilder(p_Message)

      sb.Replace(Chr(0), "{NUL}")
      sb.Replace(Chr(1), "{SOH}")

      Return sb.ToString
    End Function
Run Code Online (Sandbox Code Playgroud)

现在正如博客文章指出的那样离开StringBuilder并使用string.replace确实会产生更快的结果.(实际上,使用StringBuilder是整天这样做的最慢的方法.)

    p_Message = p_Message.Replace(Chr(0), "{NUL}")
    p_Message = p_Message.Replace(Chr(1), "{SOH}")
Run Code Online (Sandbox Code Playgroud)

知道不是每条消息都需要经历这个过程,我认为这样可以节省时间,而不必处理那些可能被遗漏的消息.所以使用正则表达式我首先搜索字符串,然后确定是否需要处理它.这与使用string.replace大致相同,基本上是节省不处理所有字符串的时间,但是用正则表达式检查所有字符串会浪费时间.

然后建议尝试使用一些与旧索引和新索引匹配的数组,并使用它来处理消息.所以它会是这样的......

Private chrArray() As Char = {Chr(0), Chr(1)}
Private strArray() As String = {"{NUL}", "{SOH}"}

Public Function TestReplace(ByVal p_Message As String) As String
    Dim i As Integer

    For i = 0 To ((chrArray.Length) - 1)
        If p_Message.Contains(chrArray(i).ToString) Then
            p_Message = p_Message.Replace(chrArray(i), strArray(i))
        End If
    Next

    Return p_Message
End Function
Run Code Online (Sandbox Code Playgroud)

到目前为止,这是我发现处理这些消息的最快方法.我已经尝试了各种其他方法来解决这个问题,比如将传入的字符串转换为字符数组并进行比较以及尝试遍历字符串而不是chrArray.

所以我的问题是:我可以加快速度吗?我错过了什么?

Jul*_*iet 1

您也许可以通过减少一些查找来提高速度。以此为例:

    If p_Message.Contains(chrArray(i).ToString) Then
Run Code Online (Sandbox Code Playgroud)

.Contains方法的复杂度为 O(n)。在最坏的情况下,您将遍历整个字符串中的所有字符而找不到任何内容,因此您希望对数组中的每个字符至少遍历一次,因此其时间复杂度为 O(nm),其中 n 是你的字符串,m是你要替换的字符数。

执行以下操作可能会获得更好的性能(我的 VB-fu 生锈了,尚未经过测试;)):

Private Function WriteToCharList(s as String, dest as List(Of Char))
    for each c as Char in s
        dest.Add(c)
    Next
End Function

Public Function TestReplace(ByVal p_Message As String) As String
    Dim chars as new List(Of Char)(p_Message.Length)

    For each c as Char in p_Message
        Select Case c
            Case Chr(0): WriteToCharList("{NUL}", chars)
            Case Chr(1): WriteToCharList("{SOH}", chars)
            Case Else: chars.Add(c);
        End Select
    Next

    Return New String(chars)
End Function
Run Code Online (Sandbox Code Playgroud)

这将p_Message最多遍历 char 两次(一次用于遍历,一次在字符串构造函数复制 char 数组时),使该函数的复杂度为 O(n)。