2 votes

Comparaison plus rapide de chaînes de caractères en vb6

J'essaie de faire en sorte que mon application vb6 fonctionne plus rapidement. vbaccélérateurs sgrid avec environ 10 000 articles en même temps (c'est une exigence du client).

J'ai dû remplir environ 20 colonnes pour chacun des 10 000 éléments, et je dois effectuer une comparaison de chaînes de caractères dans plus de la moitié d'entre elles. J'ai donc écrit une fonction de comparaison de chaînes de caractères et j'ai effectué un profilage.

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

    ' content, various versions are below

End function

actuellement les éléments = 5000 et chacun des temps ci-dessous montre le temps que cela a pris et les différentes versions de la fonction :

LCase$(Value1) = LCase$(value2)

temps : 29149 ms

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

temps : 30836 ms

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

temps 34180 ms

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

temps 28387 ms

Le chronométrage se fait avec :

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

qui renvoie le temps en millisecondes.

Est-il possible de rendre la comparaison plus rapide ?

2voto

Adrian Points 1505

Les choses qui pourraient améliorer les performances incluent..

  • Changez vos paramètres en ByRef
    • L'utilisation des paramètres ByVal permet de copier les variables sur la pile. Bien que ce soit généralement une bonne idée, si votre fonction de comparaison se comporte bien et ne modifie pas les variables, il n'est pas nécessaire de faire une copie supplémentaire des données.
  • Remplir la grille à la demande,
    • Ne remplissez que les parties de la grille qui sont affichées à l'écran - suivez cela avec les événements de mouvement de la grille. Il existe même des contrôles de grille pour VB6 qui facilitent cette opération en vous permettant de définir des éléments "virtuels" et en déclenchant des événements pour vous indiquer ceux que vous devez remplir. TList est celui que je connais le mieux - je tempère cette suggestion en précisant que son modèle de licence peut être un véritable casse-tête.

1voto

Occluded Sky Points 11

Ça devrait être assez rapide.

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

Le principe de base ici est de faire une comparaison octet par octet mod 2 sur les chaînes Unicode. L'une des fonctions ci-dessus est sensible à la casse, IsEqualB, et l'autre est insensible, IsEqual.

Bien sûr, il utilise quelques fonctions non documentées dans le runtime Visual Basic 6 : mais si vous voulez de la rapidité, c'est ce que vous devez faire, malheureusement.

0voto

Tom Studee Points 4346

Avez-vous essayé :

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

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

End function

0voto

G Mastros Points 12241

Vous pouvez probablement réduire votre temps d'exécution de moitié en utilisant "OPTION COMPARE TEXT". Placez cette ligne en haut de votre module de code.

OPTION COMPARE TEXT

Cette ligne, lorsqu'elle est utilisée, fait en sorte que la comparaison des chaînes dans le module de code ne tienne pas compte de la casse. Pour cette raison, vous pouvez simplement utiliser :

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

    IsEqual = (Value1 = Value2)

End Function

0voto

gbrooksman Points 75

Consultez l'appel WinAPI LockWindowUpdate(). Cela peut vraiment aider les grilles lorsque vous les remplissez. Veillez à l'appeler une fois pour verrouiller la fenêtre et une fois pour la déverrouiller.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X