2013-06-09 10 views
2

J'essaie de faire fonctionner mon application vb6 plus rapidement, la raison en est que je remplis vbaccelerators sgrid avec environ 10k articles en une fois (c'est une exigence du client).Comparaison de chaînes plus rapide en vb6

je devais remplir environ 20 colonnes pour chacun des 10k articles, et je dois effectuer la comparaison des chaînes dans environ plus de la moitié d'entre eux, donc j'écrit une fonction de comparaison de chaînes et ne profilage

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

    ' content, various versions are below 

End function 

actuellement les articles = 5000 et chacun des temps ci-dessous montre le temps qu'il a fallu et 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

synchronisation 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 retourne le temps en millisecondes.

Y a-t-il un moyen de rendre la comparaison plus rapide?

+0

Je pensais que l'appel d'une API pourrait être plus rapide, mais mes tests utilisant CompareStringA ont montré qu'il était 5 fois plus lent. Cela utilisait une version non compilée. Une idée que j'ai trébuché était d'utiliser des tableaux d'octets. Je ne l'ai pas testé. Bonne chance. –

+0

Le client nécessite VB6? –

+5

Vous devriez jeter un oeil sur le site [VBSpeed] (http://www.xbeat.net/vbspeed/). Ils ont une chaîne textuelle comparer. –

Répondre

2

choses qui pourraient améliorer le rendement ..

  • modifier vos paramètres afin ByRef
    • Utilisation des paramètres ByVal copies variables sur la pile. Bien que ce soit généralement une bonne idée, si votre fonction de comparaison est bien conduite et ne change pas les variables, il n'est pas nécessaire de faire une copie supplémentaire des données.
  • remplir la grille sur demande,
    • Seules les parties peuplent de la grille qui montre à l'écran - suivre ce mouvement avec les événements de la grille. Il y a même des contrôles de grille pour VB6 qui facilitent cela en vous permettant de définir des éléments «virtuels» et d'élever des événements pour vous permettre de savoir lesquels vous devez remplir. TList est celui que je connais - je vais tempérer cette suggestion avec la mise en garde que son modèle de licence peut être un vrai PITA à travailler avec.
+0

+1 pour remplir la grille sur demande – MarkJ

+0

@Adrian Qu'est-ce que Tlist? où peut-il être trouvé. Est-ce un contrôle gratuit? – Smith

+0

Bennet-Tec TList; J'ai peur, mais ses promesses de performance sont justes. http://www.bennet-tec.com/btproducts/TList/TList.htm; Je ne suis pas affilié, j'ai juste une certaine expérience en l'utilisant dans le passé. Comme je l'ai dit, le modèle d'octroi de licences est une douleur totale dans le cul, mais il est souple et puissant. – Adrian

0

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 
+0

J'ai l'impression qu'il a besoin d'une comparaison insensible à la casse, puisqu'il se met en quatre pour l'utiliser. – Adrian

+0

@TomStudee l'avez-vous référencé? c'est beaucoup plus lent – Smith

0

Vous pouvez probablement réduire votre temps d'exécution en deux à l'aide "OPTION COMPARE TEXT". Placez cette ligne en haut de votre module de code. Cette ligne, lorsqu'elle est utilisée, provoquera la comparaison de chaînes dans le module de code, sans tenir compte de la casse.En raison de cela, vous pouvez simplement utiliser:

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

    IsEqual = (Value1 = Value2) 

End Function 
+0

j'ai lu que la comparaison binaire est plus rapide que le texte – Smith

+0

Comparaison binaire est plus rapide, mais à partir de ce qui précède, la comparaison est insensible à la casse. – Adrian

0

oeil à l'appel WinAPI LockWindowUpdate(). Cela peut vraiment aider les grilles lorsque vous les peupler. Assurez-vous de l'appeler une fois pour verrouiller la fenêtre et une fois pour la déverrouiller.

0

Cela devrait être plutôt 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 

La prémisse de base ici est de faire un byte by by par comparaison mod 2 sur les chaînes Unicode. L'une des fonctions ci-dessus est sensible à la casse, IsEqualB, alors que l'autre est insensible IsEqual.

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