Jochens Weblog

ESCde Developer Blog

  Home :: Kontakt :: RSS Feed
  12 Posts :: 0 Artikel :: 4 Kommentare :: 0 Trackbacks

Archiv

Post Kategorien

ESCde

ESCde Blogger

Oftmals kommt man als Entwickler in die Verlegenheit, dass große Mengen von Objekten in kurzer Zeit erstellt werden müssen. Ein gutes Beispiel hierfür sind Algorithmen, welche während ihrer Laufzeit viele Objekte benötigen um Zustände und Zwischenergebnisse zu speichern.

Üblicherweise werden diese Objekte genau zu dem Zeitpunkt erstellt, zu dem sie auch benötigt werden, also mitten im Algorithmus. Das Erzeugen dieser Objekte kann allerdings recht teuer sein, wenn man bedenkt, dass die .NET Runtime hierzu erst passenden Speicher finden und reservieren muss.
Die Anzahl der verwendeten Objekte steht meist in Relation zu der Problemgröße, beispielsweise der Anzahl an untersuchten Dateien, der Größe eines Eingabearrays oder Ähnlichem. Hierdurch hat man meist schon vor dem Start des Algorithmus eine Ahnung, wie viele Objekte wohl benötigt werden. Dieses Wissen möchten wir uns hier nun zu Nutze machen.

Weiß man nämlich bereits vorab, wie viele Objekte benötigt werden, kann man diese bereits vor dem Ablauf des Algorithmus anlegen und die eigentliche Rechenzeit des Algorithmus somit verkürzen. Nehmen wir einmal an, Ihr Algorithmus würde während seiner Laufzeit viele Objekte des folgenden Typs benötigen:

class MemoryChunk { public int[] iData = new int[100]; }

Diese Klasse ist zwar recht unkompliziert, verlangt der .NET-Runtime jedoch einiges ab. Für eine Anwendung wäre es ein deutlicher Vorteil, wenn das erstellen dieser „Speicherklumpen“ bereits vorbereitet werden könnte.

Zu diesem Zweck erstellen wir eine weitere Klasse, den ObjectCreator:

class ObjectCreator<TargetType> where TargetType : class , new() { private TargetType[] mObjects; int mIndex = 0; public ObjectCreator() { } public void CreateObjects(int iCount) { if (iCount > 0) { mIndex = iCount - 1; mObjects = new TargetType[iCount]; for (int i = 0; i < iCount; i++) { TargetType obj = new TargetType(); mObjects[i] = obj; } } } public TargetType NewObject() { if (mIndex > 0) { TargetType obj = this.mObjects[mIndex]; mIndex--; return obj; } else return null; // oder: else return new TargetType(); } }

Wie Sie sehen handelt es sich hierbei um eine generische Klasse. TargetType gibt hierbei den Typ der zu erstellenden Objekte an, beispielsweise MemoryChunk. Durch Aufruf der Methode CreateObjects(AnzahlObj) können Sie ObjectCreator dazu veranlassen, AnzahlObj Objekte anzulegen. Durch Aufruf der Methode NewObject wird nun nach und nach je eines dieser Objekte zurückgegeben.

Die Anwendung der Klasse liegt nun auf der Hand: Wissen Sie beispielsweise, dass Ihr (gleich startender) Algorithmus 800 MemoryChunk-Objekte benötigt, erstellen Sie eine Instanz der Klasse ObjectCreator und rufen CreateObjects auf:

ObjectCreator<MemoryChunk> Creator = new ObjectCreator<MemoryChunk>(); Creator.CreateObjects(800);

Alle Codezeilen, in denen Sie innerhalb des Algorithmus ein MemoryChunk-Objekt erstellen, z.B. durch:

MemoryChunk mem = new MemoryChunk();

können Sie nun durch den folgenden Aufruf ersetzen:

MemoryChunk mem = Creator.NewObject();

Da die hier zurückgegebenen Objekte bereits existieren, werden Sie durch eine deutlich beschleunigte Laufzeit belohnt.

Nun kann man richtigerweise einwenden, dass die Objekte so oder so erstellt werden müssen, in der Summe sollte der Aufwand daher gleich bleiben. Dies ist so sicher richtig, allerdings gibt es viele Situationen, in denen man die „gesammelte“ Objekterstellung in Zeiten des Leerlaufs unterbringen kann. Nehmen Sie beispielsweise an, der Anwender fügt Einträge in einer Liste ein, welche anschließend von einem Algorithmus verarbeitet werden sollen. Während der Anwender den Mauszeiger zum Menüpunkt des Algorithmus bewegt, besteht genug Zeit, die nötigen Objekte vorab zu erstellen und die Wartezeit aufgrund der Abarbeitung für den Anwender zu minimieren.

veröffentlicht am 08.09.2006 15:05

Kommentare

Bisher kein Feedback.

Kommentar abgeben

Titel:
Name:
Email:
(wird nicht angezeigt!)
Homepage:
Feedback:
Please add 4 and 8 and type the answer here: