Visual Basic - Technik, FAQ, Tricks, Beispiele

Home / Daten / Strings / Concat

Strings schnell aneinander hängen

Impressum
Kontakt
DSVGO
Historie
19.12.2000Durch Nutzung von MidB$ und LeftB$ konnte der Code nochmal deutlich beschleunigt werden
27.11.2000Code-Abschnitt für Buffer-Vergrößerung korrigiert (bisher wurden dabei die bereits angefügten Strings "vergessen")
03.11.2000Erste Version

Das Problem

Eine der langsamsten Operationen in VB ist das Aneinanderhängen von Strings (die sogenannte "Konkatenation") mit Hilfe des Zeichenketten-Operators "&". Bei der Ausführung des folgenden Codes wird intern bei jedem Schleifen-Durchlauf eine neuer String generiert:
Dim i As Long
Dim s As String

For i = 1 To 10000
  s = s & "x"
Next i
Print s
Das Erzeugen von 10.000 neuen Strings fordert VB sehr stark: auf meinem Rechner (bei voll optimierender Kompilierung) dauert dies 294ms.

Die Lösung

Ich habe eine Klasse erstellt, die intern (fast) keine neuen Strings erzeugt. Dies gelingt mit Hilfe des Mid$-Statements, mit welchem es möglich ist, direkt in einen bestehenden String zu schreiben. Der obige Code kann mit der Concat-Klasse dann so geschrieben werden:
Dim i As Long
Dim cc As Concat

Set cc = New Concat
For i = 1 To 10000
  cc.Concat "x"
Next i
Print cc.Value
Die Ausführung dieses Codes dauert bei mir nur 8ms. Die Concat-Klasse arbeitet also weit über 30-mal schneller als der &-Operator von VB.

Der Code

Legen Sie ein neues Klassenmodul mit dem Namen "Concat" an. Speichern Sie es als "Concat.cls". Fügen Sie dann den folgenden Code ein:
Option Explicit

Private Buffer As String
Private BufferLen As Long
Private Pointer As Long

'Auf "Leerstring" setzen:
Public Sub Clear()
  Pointer = 1
End Sub

'String anhängen:
Public Sub Concat(ByRef Value As String)
  Dim PointerNew As Long
  
  'Benötigten Buffer berechnen:
  PointerNew = Pointer + LenB(Value)
  
  'Ggf. Buffer vergößern:
  If PointerNew > BufferLen Then
    Buffer = Buffer & Space$(PointerNew)
    BufferLen = LenB(Buffer)
  End If
  
  'String passend kopieren:
  MidB$(Buffer, Pointer) = Value
  Pointer = PointerNew
End Sub

'Länge des internen Strings:
Public Property Get Length() As Long
  Length = Pointer \ 2
End Property

'Inhalt des internen Strings:
Public Property Get Value() As String
  Value = LeftB$(Buffer, Pointer - 1)
End Property

'Neues Objekt initialisieren:
Private Sub Class_Initialize()
  Clear
End Sub

© Jost Schwider, 03.11.2000-19.12.2000 - http://vb-tec.de/concat.htm