Geschwindigkeit ist keine Hexerei: Kleine Kniffe, die den Programmablauf beschleunigen

Viele Programmierer fragen sich, warum andere Programme schneller laufen als die eigenen. Manch einer führt dies auf die eigene Entwicklungssoftware zurück oder mutmaßt, daß die fremde Software in Assembler geschrieben ist.

Dabei sind es meistens kleine Tricks und besondere Algorithmen, die einem Programm richtig Dampf machen. Eine Auswahl solcher Tips und Tricks finden Sie an anderer Stelle in dieser Ausgabe. Einige Spezialitäten behandeln wir hier ausführlicher.

Jeder, der sich auf dem ST mit Bildern und Rastergrafiken beschäftigt, steht vor dem Problem, gepackte Dateien wie GEM-Image- oder Degas-Elite-Biider laden zu müssen. Kein Problem, hört man es laut schallen: Datei laden, im Speicher entpacken und fertig.

Dies geht gut, solange die Bilder in ihrer Größe dem Atari-Bildschirmformat entsprechen. Was aber tun, wenn eine gescannte Vorlage mit einer Auflösung von 3200 x 4400 Pixeln vorliegt — dies entspricht einer mit 400 dpi gescannten DIN-A4-Seite. Das unkomprimierte Bild setzt sich aus ca. 1,7 MByte Informationen zusammen. Ein Mega ST2 kann solche Grafiken gerade noch im Speicher halten.

Bilder und Texte blitzschnell in den Speicher laden

Viele Programme entpacken die Bilder auf dem Massenspeicher und lesen nur soviele Daten, wie sie gerade benötigen.

Programme wie »Degas Elite« zeigen deutlich den großen Nachteil dieses Verfahrens: Durch die vielen Dateizugriffe, die beim ST nicht zu den schnellsten gehören, leidet die Geschwindigkeit sehr. Ein weiterer Vertreter dieser Gattung ist der allseits bekannte Komprimierer »ARC«. Er stellt beim Anlegen eines größeren Archivs Ihre Geduld auf eine harte Probe.

Um dieses Dilemma erst gar nicht aufkommen zu lassen, gehen Sie folgendermaßen vor: Zuerst ermitteln Sie die Maße des Rasterbildes und damit die Größe des benötigten Speichers.

Alle Rasterbildformate mit variabler Größe, z.B. GEM-Image, IFF oder TIFF, speichern diese Informationen in einem Header. Den benötigten Speicher reservieren Sie. Danach reservieren Sie den gesamten restlichen Speicher. In den zweiten Speicherblock laden Sie immer so viele Bilddaten, wie gerade noch hineineinpassen. Nun entpacken Sie das Bild, soweit es im Speicher vorhanden ist.

Erreichen Sie das Ende des Speicherblocks, aber nicht das des gesamten Bildes, schieben Sie den noch nicht entpackten Rest an den Anfang des Speicherblocks. Dahinter laden Sie die nächste Portion der Datei vom Massenspeicher.

Dies wiederholt sich, bis das gesamte Bild entpackt ist. Die Diskettenzugriffe reduzieren sich so von mehreren hundert auf einige wenige, deren Anzahl von der Bildgröße und vom vorhandenen Speicher abhängig ist.

Noch einfacher und schneller ist folgende Methode: Nachdem Sie, wie oben beschrieben, den Header ausgewertet haben, reservieren Sie den benötigten Speicherplatz. Die komprimierte Datei laden Sie an das Ende dieses Speicherbereichs und entpacken sie. Dabei dürfen die Bilddaten bereits entpackte Bereiche der Datei überschreiben. Leider führt diese Methode nicht immer zum Ziel. Es besteht beispielsweise die Möglichkeit, daß die komprimierte Datei länger ist als das unkomprimierte Bild. Dies ist mit GEM-Images leicht zu realisieren. Außerdem arbeiten einige Kompressionsalgorithmen nicht sequentiell, so daß beim Überschreiben der komprimierten Daten noch benötigte Bildteile verlorengehen.

Ein weiterer Punkt, an dem sich viel Zeit sparen läßt, ist das Laden von Textdateien. Viele Programme lesen Texte zeilenweise. Jede höhere Programmiersprache bietet hierfür die nötigen Routinen. Basic wartet mit dem INPUT-Befehl, Pascal mit den Prozeduren READ und READLN und C sogar mit einer ganzen Anzahl von Befehlen auf.

Es erfordert eine Menge Geduld, auf diese Weise große Texte, beispielsweise HPGL-, Postscript- oder DXF-Dateien zu lesen. Auch hier ist eine Routine vorteilhaft, die größere Blöcke lädt und sie erst im Speicher in einzelne Zeilen entpackt.

Um den Unterschied zwischen diesen beiden Verfahren zu demonstrieren, nehmen Sie GFA-Basic 3.0 und lesen in einer Schleife tausend Zeilen in ein Stringarray. Benutzen Sie anschließend zum Vergleich für dieselbe Aktion den Befehl RECALL. Die zweite Variante ist um ein Vielfaches schneller.

Ein Trick, Datenschreibzugriffe zu optimieren

Alles über das Lesen von Dateien gilt natürlich auch, wenn man Dateien schreibt. Die Daten in größere Blöcke aufzubereiten, spart beim Speichern eine Menge wertvoller Zeit. Arbeiten Sie mit dem ROM-TOS oder dem Blitter-TOS, dann ist folgender kleine Tip zum Umgang mit Festplatten für Sie von Interesse: Angenommen, Sie arbeiten mit einer Stammdatei, an die Sie regelmäßig Ihre neuen Daten anhängen — also beispielsweise mit einer Adreßverwaltung. Dann ist es sinnvoll, die Datei gleich so groß anzulegen, daß Sie sie später nicht mehr erweitern müssen. Die Cluster einer bereits vorhandenen Datei finden die alten GEMDOS-Versionen nämlich wesentlich schneller als die freien Sektoren einer Festplatte. Außerdem beugen Sie so der Meldung »DISKETTE VOLL« wirkungsvoll vor.

Wir hoffen, daß unsere kleinen Kniffe Ihren selbstprogrammierten Anwendungen auf die Sprünge helfen, wenn es um Arbeitsgeschwindigkeit geht. Denn oft beschleunigt bereits eine winzige Änderung im Quellcode den Programmablauf enorm. (uh)


Michael Bernards
Aus: ST-Magazin 10 / 1989, Seite 24

Links

Copyright-Bestimmungen: siehe Über diese Seite