2

我试图让我的 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 毫秒

(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

它以毫秒为单位返回时间。

反正有没有让比较更快?

4

5 回答 5

2

可能会提高性能的事情包括..

  • 将参数更改为 ByRef
    • 使用 ByVal 参数将变量复制到堆栈上。虽然这通常是一个好主意,但如果您的比较函数表现良好并且不会更改变量,则不需要额外复制数据。
  • 按需填充网格,
    • 仅填充屏幕上显示的网格部分 - 使用网格移动事件进行跟踪。甚至还有用于 VB6 的网格控件,通过让您定义“虚拟”项和引发事件来让您知道需要填充哪些项来促进这一点。TList 是我熟悉的那个——我会缓和这个建议,但要注意它的许可模型可以是一个真正的 PITA。
于 2013-06-09T22:54:51.870 回答
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 运行时中使用了几个未记录的函数:但不幸的是,如果您想要速度,那就必须这样做。

于 2014-05-22T10:40:10.043 回答
0

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

于 2013-06-11T15:54:04.457 回答
0

你有没有尝试过:

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

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

End function
于 2013-06-09T22:44:50.717 回答
0

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

OPTION COMPARE TEXT

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

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

    IsEqual = (Value1 = Value2)

End Function
于 2013-06-10T15:29:34.040 回答