Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs
ASP German Homepage Homepage
 

Liste

.NET 2.0 (1)
.NET Allgemein (16)
.NET Fu (5)
ADO.NET (11)
Aprilscherz (3)
ASP Grundlagen (44)
ASP Tricks (83)
ASP.NET (44)
ASPIntranet.de (5)
C# (28)
Datenbank (44)
Dokumentation (4)
IIS 6.0 (1)
Komponenten (29)
Optimierung (10)
Server (21)
Sicherheit (34)
Tee Off (6)
VB.NET (6)
WAP (8)
Web Services (11)
XML (9)

RSS 2.0 - Die neuesten fünf Artikel auf AspHeute.com


 

Suchen





 

English Articles
Chinese Articles
Unsere Autoren
 
Link zu AspHeute
Impressum
Werben
Anfragen

Die Performancefalle ReDim Preserve

Geschrieben von: Christoph Wille
Kategorie: VB.NET

Wer mit Arrays in VB arbeitet, dem wird auch das ReDim Statement zum Verändern der Größe eines Arrays nicht unbekannt sein. Heute werde ich Ihnen ausführlich darlegen, warum Sie dieses Statement in Zukunft besser nicht mehr, oder nur noch sehr, sehr selten einsetzen sollten.

Die Einsatzmöglichkeiten von ReDim

Bevor ich jetzt über das ReDim Statement herfalle und es zerzause, möchte ich noch einmal die üblichsten Anwendungsfälle anhand eines Codebeispiels zeigen (redimsamples.aspx). Dabei handelt es sich um das simple ReDim, als auch ReDim Preserve:

<% @Page Language="VB" %>
<%
Dim arrStrings(1) as String
Response.Write(UBound(arrStrings) & "<br>")

ReDim arrStrings(20)
Response.Write(UBound(arrStrings) & "<br>")

ReDim Preserve arrStrings(25)
Response.Write(UBound(arrStrings) & "<br>")
%>

ReDim erlaubt es, ein Array zu vergrößern oder zu verkleinern. Dabei wird immer ein neues Array angelegt. Der Grund hierfür ist, daß das VB.NET Array vom System.Array der .NET Runtime hergeleitet ist, und dieses per Definition eine ab Ersterstellung fixe Größe hat. In C# ist das offensichtlich, wie der folgende Code - der ReDim emuliert - zeigt:

string[] arrTest = new string[1];
// und jetzt wollen wir die Größe verändern: ReDim arrTest(20)
arrTest = new string[20];

An sich ist das kein Problem, das Problem kommt erst mit Preserve (unser heutiges Thema). Wenn man Redim mit dem Schlüsselwort Preserve verwendet, so werden die alten Elemente beibehalten - als Kopie im neuen Array.

ReDim Preserve als Performancekiller

Im Prinzip ist die Katze bereits aus dem Sack - das ReDim Preserve Statement erzeugt ein neues Array - und die Elemente des alten Arrays werden in das neue kopiert. Da dies unter VB.NET (wie auch im "alten" VB) implizit passiert, merkt man außer schlechter Performance nichts. Um es etwas krasser zu zeigen, habe ich einen Loop gebastelt, der ein Array fünftausend Mal ReDimmed (redimloop.aspx).

<% @Page Language="VB" Trace="True" %>
<%
Dim arrStrings() as String
Dim i as Integer

Trace.Write("Redim","Start")

For i = 1 To 5000
  ReDim Preserve arrStrings(i)
  arrStrings(i-1) = i
Next

Trace.Write("Redim","End")
%>

Da ich Tracing eingeschaltet habe, kann ich sehr einfach die Performancedaten ermitteln:

Natürlich wird das mit jedem Aufruf etwas differieren (und mit der Maschine), aber man bekommt einen groben Anhaltspunkt für die Performance - und es zählt ja die Relativperformance auf ein und derselben Maschine.

Was passiert aber im Hintergrund, wenn man ReDim Preserve aufruft? Um es zu illustrieren, habe ich das ReDim Statement in C# nachgebaut - weil dort muß man alles händisch machen, was ReDim in VB.NET automatisch hinter den Kulissen veranstaltet (redimloopexplicit.aspx).

<% @Page Language="C#" Trace="True" %>
<%
string[] arrStrings = new string[1];
int i;

Trace.Write("Redim","Start");

for (i=1;i<=5000;i++)
{
  string[] arrHelper = new string[i];
  arrStrings.CopyTo(arrHelper, 0);
  arrHelper[i-1] = i.ToString();
  arrStrings = arrHelper;
}

Trace.Write("Redim","End");
%>

Hier sieht man deutlich, wie schlecht die Performance sein muß - zuerst wird ein Array der neuen Größe angelegt, und dann der Inhalt des alten Arrays in das neue kopiert. Die Laufvariable wird zugewiesen, wobei ich in C# den Cast zu String selbst machen muß. Und zu guter letzt wechsle ich die Arrayvariablen aus.

Wer glaubt, VB.NET macht was anderes, der irrt - die Performance ist haarklein dieselbe wie ReDim Preserve (mein Code ist vielleicht eine Spur besser, weil ich das Verkleinern des Arrays nicht berücksichtige). Wie schlecht die Performance tatsächlich ist, sieht man allerdings erst im Vergleich mit einer besseren Technologie - der ArrayList Klasse.

Die beste Lösung - ArrayLists

Die beste Lösung für ein dynamisches Array ist die ArrayList Klasse aus dem System.Collections Namespace. Eine ArrayList kann dynamisch wachsen und schrumpfen, und ist in der Verwendung äußerst einfach (arraylistloop.aspx):

<% @Page Language="VB" Trace="True" %>
<% @Import Namespace="System.Collections" %>
<%
Dim arrList as New ArrayList(100)
Dim i as Long

Trace.Write("ArrayList","Start")

For i = 1 To 50000
  arrList.Add(i)
Next

Trace.Write("ArrayList","End")
%>

Wer genauer hinsieht wird bemerkt haben, daß der Loop nicht bis fünftausend, sondern bis fünfzigtausend läuft - der Grund: mit fünftausend konnte ich die Performance nicht messen. Aber mit fünfzigtausend ist sie immer noch sehr beeindruckend:

Die Ausführungszeit ist 0.01 zu 0.45 - und das obwohl der Loop zehn Mal öfters läuft! Ich wollte ReDim Preserve ebenfalls mit dieser Anzahl laufen lassen, habe aber dann irgendwann den Server resetted...

Schlußbemerkung

Die Quintessenz des Artikels ist daß man unter VB.NET dringend die Finger von ReDim Preserve lassen sollte. Wenn man veränderbare Arrays braucht, sollte man statt dessen zur ArrayList greifen, die sich sowieso fast wie ein normales Array verhält.

Download des Codes

Klicken Sie hier, um den Download zu starten.

Verwandte Artikel

Verwendung von Arrays in C#
Wetterbericht per SMS versenden

Wenn Sie jetzt Fragen haben...

Wenn Sie Fragen rund um die in diesem Artikel vorgestellte Technologie haben, dann schauen Sie einfach bei uns in den Community Foren der deutschen .NET Community vorbei. Die Teilnehmer helfen Ihnen gerne, wenn Sie sich zur im Artikel vorgestellten Technologie weiterbilden möchten.

Eine weitere sehr hilfreiche Resource ist das deutsche ASP.NET Wiki, das als zentrale Anlaufstelle für Tips, Tricks, Know How und alles Nützliche was man in seinem Alltag als (ASP).NET-Entwickler so braucht und entdeckt gedacht ist.

Haben Sie Fragen die sich direkt auf den Inhalt des Artikels beziehen, dann schreiben Sie dem Autor! Unsere Autoren freuen sich über Feedback zu ihren Artikeln. Ein einfacher Klick auf die Autor kontaktieren Schaltfläche (weiter unten) und schon haben Sie ein für diesen Artikel personalisiertes Anfrageformular.

 

Und zu guter Letzt möchten wir Sie bitten, den Artikel zu bewerten. Damit helfen Sie uns, die Qualität der Artikel zu verbessern - und anderen Lesern bei der Auswahl der Artikel, die sie lesen sollten.

Bewerten Sie diesen Artikel
 Sehr gut   Nicht genügend  
   1  2  3  4  5  
 

  
   Für Ausdruck optimierte Seite

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.