vb6中的字符串比较更快

时间:2013-06-09 18:51:11

标签: performance vb6 comparison

我试图让我的vb6应用程序运行得更快,原因是我一次用大约10k项填充 vbaccelerators sgrid (这是客户端的要求)。

我必须为每个10k项填充大约20列,并且我必须在大约一半以上的字符串中进行字符串比较,所以我写了一个字符串比较函数并进行了分析

Function IsEqual(byval value1 as string, Byval value2 as string) as boolean

    ' content, various versions are below

End function

目前items = 5000,下面的每个时间都显示了所花费的时间和各种版本的功能:

LCase$(Value1) = LCase$(value2)

时间:29149 ms

(StrComp(Value1, value2, 1) = 0 )

时间:30836毫秒

If StrComp(Value1, value2, 1) = 0 Then
    IsEqual = True
Else
    IsEqual = False
End If

时间34180毫秒

If StrComp(Value1, value2, 1) = 0 Then IsEqual = True

时间28387毫秒

时间安排:

Declare Function timeBeginPeriod Lib "winmm.dll" (ByVal uPeriod As Long) As Long
Declare Function timeEndPeriod Lib "winmm.dll" (ByVal uPeriod As Long) As Long
Declare Function timeGetTime Lib "winmm.dll" () As Long

以毫秒为单位返回时间。

是否有更快的比较?

5 个答案:

答案 0 :(得分:2)

可能提高绩效的因素包括......

  • 将参数更改为ByRef
    • 使用ByVal参数将变​​量复制到堆栈中。虽然这通常是一个好主意,但如果您的比较函数表现良好且不会更改变量,则无需额外复制数据。
  • 按需填充网格,
    • 仅填充屏幕上显示的网格部分 - 使用网格移动事件跟踪此部分。甚至还有VB6的网格控件,通过让您定义“虚拟”项目和引发事件来让您知道需要填充哪些项目来实现此目的。 TList是我熟悉的那个 - 我会用这个警告来缓和这个建议,认为它的许可模式可以成为真正的PITA。

答案 1 :(得分:1)

这应该很快。

Option Explicit

Private Declare Sub DerefByte Lib "msvbvm60" Alias "GetMem1" (ByVal Add As Long, ByRef Value As Byte)
Private Declare Sub DerefLong Lib "msvbvm60" Alias "GetMem4" (ByVal Add As Long, ByRef Value As Long)

Private Sub Form_Load()

    Debug.Print IsEqual("Hello", "hello")
    Debug.Print IsEqualB("Hello", "hello")

End Sub

Public Function IsEqualB(Str1 As String, Str2 As String) As Boolean

    Dim lpS1 As Long, lpS2 As Long
    Dim t1 As Byte, t2 As Byte
    Dim lSz As Long
    Dim i As Long

    IsEqualB = True

    lpS1 = StrPtr(Str1)
    lpS2 = StrPtr(Str2)
    DerefLong lpS1 - 4, lSz

    If lSz = LenB(Str2) Then
        For i = 0 To lSz - 1 Step 2
            DerefByte lpS1 + i, t1
            DerefByte lpS2 + i, t2
            If Not (t1 = t2) Then
                IsEqualB = False
                Exit For
            End If
        Next
    Else
        IsEqualB = False
    End If

End Function

Public Function IsEqual(Str1 As String, Str2 As String) As Boolean

    Dim lpS1 As Long, lpS2 As Long
    Dim t1 As Byte, t2 As Byte
    Dim lSz As Long
    Dim i As Long

    IsEqual = True

    lpS1 = StrPtr(Str1)
    lpS2 = StrPtr(Str2)
    DerefLong lpS1 - 4, lSz

    If lSz = LenB(Str2) Then
        For i = 0 To lSz - 1 Step 2
            DerefByte lpS1 + i, t1
            DerefByte lpS2 + i, t2
            If Not (t1 Or &H20) = (t2 Or &H20) Then
                IsEqual = False
                Exit For
            End If
        Next
    Else
        IsEqual = False
    End If

End Function

这里的基本前提是在Unicode字符串上逐字节比较mod 2。上述函数之一是区分大小写的,IsEqualB,然后其他函数是不敏感的IsEqual。

当然,它在Visual Basic 6运行时中使用了几个未记录的函数:但是如果你想要速度,不幸的是,这就是你必须做的事情。

答案 2 :(得分:0)

你试过了吗?

Function IsEqual(byval value1 as string, Byval value2 as string) as boolean

    Return StrComp(LCase$(Value1), LCase$(value2), vbBinaryCompare) = 0

End function

答案 3 :(得分:0)

您可以使用“OPTION COMPARE TEXT”将执行时间缩短一半。将此行放在代码模块的顶部。

OPTION COMPARE TEXT

此行在使用时将导致代码模块中的字符串比较不区分大小写。因此,您可以简单地使用:

Function IsEqual(byval value1 as string, Byval value2 as string) as boolean

    IsEqual = (Value1 = Value2)

End Function

答案 4 :(得分:0)

查看LockWindowUpdate()WinAPI调用。当你填充网格时,这可以真正帮助网格。确保调用一次锁定窗口,然后解锁一次。