DevTrain Startseite Advanced Developers Conference vom 14.-15. Februar 2011  
  
  
SUCHEN:  
ARTIKEL ONLINE: 525   

Kategorien
.NET
Datenbanken
Web
XML

Allgemein
Camp
Foren
Events
Persönliche Einstellungen
Registrieren
Prämien Shop
Kontakt
Impressum
Über DevTrain

Autoren


   Autor: Bernhard Elbl Artikel Drucken
        
Das Gaspedal für String-OP´s in VB6

String-Operationen sind wohl in den meisten Anwendungen zu finden. Sie gehören zu den absoluten Basics beim Codieren von Anwendungen in jeder Programmiersprache. In VB6 sind String-OP´s sehr sehr langsam und es wird vor Ihrer Verwendung immer gewarnt. Trotzdem wird man nie ohne Sie auskommen. Das einfache String-Building ist also langsam, und es wird Zeit, dass wir ihm ein Gaspedal verpassen. Thema heute ist das Generieren von Strings in Wiederholungen in VB6.

Nehmen wir dafür folgendes einfaches Beispiel vor:
For i = 0 to 5
 b = b & "A"
Next
Wir bauen uns einen String das 6 "A" enthält.  Wieviele Zeichen werden jetzt in b kopiert?
Beim 1. Durchgang ist es 1 Zeichen.
Beim 2. Durchgang werden 2 Zeichen (b="A" und "A") kopiert! Jetzt sind wir bei insgesamt 3 Zeichen!
Beim 3. Durchgang: b = b(="AA") & "A" ==> das sind ein plus von 3 Zeichen also haben wir bereits 6 Zeichen kopiert!! usw usw...
Also ergibt sich folgende Rechnung:
Anzahl von zu kopierenden Zeichen: 1+2+3+4+5+6 = 21 Zeichen!!!

Mehr dazu ist in 25 ASP TIPP´s zu finden.
http://dblabor.f4.fhtw-berlin.de/Lehre/asptips.htm

Wie kann man das Verbessern?
In dem wir Speicher reservieren und den String in den reservierten Speicher kopieren. Hier können wir als Ziel ein Byte-Array verwenden, da ASCII-Zeichen zum Byte-Format voll kompatibel sind. Das kopieren erledigen wir mit der API "CopyMemory".

Wie schnell kann es dadurch werden?
Sehr schnell! Folgendes Beispiel zeigt 10000 Wiederholungen, wobei der Wert "ppedv AG" immer und immer wieder angefügt wird. Hier ist der Vergleich zwischen Normal (b = b & "wert") und der "CStringBuilder"-Klasse.

2,8 Sekunden mit Normal und 0,06 Sekunden mit der CStringBuilder-Klasse! Getestet mit einem P3, 500MH und Win2000.
Das Sample mit allen Sources gibt es unten zum Download.

Das Verwenden der Klasse ist sehr einfach.
statt (Normal)...

    For i = 0 To 10000
        sVal = sVal & "ppedv AG"
    Next
    txtErg.Text = sVal

folgendes (CStringBuilder)...

    Dim oStrBuilder As New CStringBuilder
    For i = 0 To 10000
        oStrBuilder.Add "ppedv AG"
    Next
    txtErg.Text = oStrBuilder.Value



Werfen wir einen Blick auf die Klasse "CStringBuilder"!

Option Explicit

Private m_abyteString() As Byte ' beinhaltet (B)Strings als Byte-Array
Private m_lSize As Long ' beinhaltet die tatsächliche Grösse des gesamten Strings in Byte (Anzahl der Zeichen * 2)

' Kopiert Speicher-Bereiche.
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

' Die Add Funktion ist der Kern der Klasse und erledigt das Anfügen von Strings
' wie b = b & "wert"
Public Sub Add(ByVal Value As String)
    Dim lSize As Long
   
    ' Länge in Byte = Zeichen * 2
    lSize = LenB(Value)
   
    On Error GoTo Fehler
   
    ' vor Array-Buffer-Überlauf die Grösse des Arrays verdoppeln.
    If (m_lSize + lSize) > (UBound(m_abyteString) + 1) Then
        ReDim Preserve m_abyteString((UBound(m_abyteString) * 2) + 1)
    End If
   
    ' String-Wert zu Byte-Array hinzufügen.
    CopyMemory ByVal VarPtr(m_abyteString(m_lSize)), ByVal StrPtr(Value), lSize
   
    m_lSize = m_lSize + lSize ' reale String-Grösse in Byte speichern
   
    Exit Sub
Fehler:
    If Err.Number = 9 Then
        '.....
    Else
        Err.Raise Err.Number, Err.Source, Err.Description
    End If
End Sub

' Diese Funktion stellt den erstellten String-Wert bereit.
' Byte-Array und String sind als kompatible Datentypen.
Public Property Get Value() As String
    Value = CStr(LeftB(m_abyteString, m_lSize))
End Property

' Buffer-Grösse festlegen(Let) und veräussern(Get)
Public Property Let BufferSize(ByVal par As Long)
    ReDim m_abyteString((par * 2) - 1) '--> in Byte-Länge konvertieren
End Property

Public Property Get BufferSize() As Long
    On Error GoTo Fehler
    BufferSize = (UBound(m_abyteString) + 1) / 2 '--> in Zeichen-Länge konvertieren
   
    Exit Property
Fehler:
    Err.Clear
    BufferSize = 0
End Property

Private Sub Class_Initialize()
    ReDim m_abyteString(511) ' Default String-Buffer festsetzen
End Sub

BufferSize
Mit Hilfe der "BufferSize"-Eigenschaft kann die Grösse des String-Buffers optimiert werden. Natürlich nur, wenn man weiss wie Gross die Zeichenkette werden wird. Dann muss das Byte-Array nicht mehr resized werden und das spart zusätzlich etwas Zeit.

Alle Sources gibt´s unten zum Download.

 

 


 


DevTrain Camp - Schneller zum .NET 3.5 Developer
 
Verwandte Artikel      Verlinkte Dokumente
    Keine verknüpften Dokumente

  Erfasst am: 19.03.2002
  Gültig bis: 18.04.2002
0 Ratings
Bewertung: 0,0%
schlecht    sehr gut  

 
© Copyright 2007 ppedv AG