Rubrik: Variablen/Strings | VB-Versionen: VB.NET | 03.03.03 |
Effizent Zeichenketten zusammensetzen Beispiel, wie sich die Perfomance erheblich steigern lässt, wenn man Zeichenketten mit der StringBuilder Klasse zusammensetzt. | ||
Autor: Thorsten Thiel | Bewertung: | Views: 22.940 |
www.eclere.de | System: Win9x, WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 | Beispielprojekt auf CD |
In VB.Net sind Zeichenketten unveränderlich. Das heisst, bei jeder String-Operation, die eine Zeichenkette verändert, wird die alte Zeichenkette verworfen und eine neue erzeugt. Das wäre keine Problem, würde die alte Zeichenkette sich nicht mehr im Speicher befinden. Jedoch passiert das erst nach einer Weile. Der daraus resultierende Code ist geradezu unlaublich langsam.
Beispiel: Innerhalb einer Schleife wird eine Zeichenkette erweitert:
Dim Str as String Dim i as Integer For i = 1 to 10000 Str += "Zeile " & i & vbcrlf Next i
Hier wird pro Durchgang eine neue Zeichenkette angelegt. Das sind 10000, wovon 9999 wieder freigegeben werden müssen. Hinzu kommt noch, dass bei jedem Schleifendurchlauf die alte Zeichenkette in die neue kopiert werden muss.
Abhilfe schaft hier die StringBuilder-Klasse.
Die Text.StringBuider-Klasse ermöglicht es Zeichenketten zusammenzusetzen, wobei versucht wird die Zeichenkette am selben Ort im Speicher zu belassen. Leider stehen in dieser Klasse nur sehr wenige Methoden zur Verfügung:
Dim str as New System.Text.StringBuilder ' hängt einen Text an einen String an str.Append ("Text") ' fügt Text an eine bestimmte Position ein str.Insert (5,"Text") ' löscht einen Text str.Remove(2,3) ' ersetzt einen Text str.Replace ("Text","Text2")
Dass sich der Einsatz der StringBuilder-Klasse wirklich lohnt zeigt das folgende Beispiel. Es durchläuft 5000 mal eine Schleife und berechnet anschließend die benötigte Zeit.
Benötigt werden:
1 Form
2 MultiLine-TextBoxen
2 Buttons
2 Labels
Und hier der Code:
Const loopsize As Integer = 5000 Dim str As String Dim starttime As Date Dim totaltime As TimeSpan
Private Function WithStrBuilder() As String Dim strB As New System.Text.StringBuilder() Dim strLine As String Dim i As Integer For i = 1 To loopsize strLine = "1/i = " & 1 / i & vbCrLf strB.Append(strLine) Next i Return strB.ToString End Function
Private Function WithoutStrBuilder() As String Dim strT As String Dim i As Integer For i = 1 To loopsize strT += "1/i = " & 1 / i & vbCrLf Next i Return strT End Function
Private Sub Button2_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button2.Click starttime = Now str = WithStrBuilder() TextBox2.Text = str totaltime = Now.Subtract(starttime) Label2.Text = (Format(totaltime.TotalSeconds, _ "Zeit: #.##### Sekunden")) End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click starttime = Now str = WithoutStrBuilder() TextBox1.Text = str totaltime = Now.Subtract(starttime) Label1.Text = (Format(totaltime.TotalSeconds, _ "Zeit: #.##### Sekunden")) End Sub
Wenn Sie das Beispiel jetzt starten, sehen Sie es ganz deutlich: Der Einsatz der StringBuilder-Klasse ist in etwa 500 mal schneller gegenüber dem herkömlichen Code!