Nachbrenner für Save/Load von Feldern in GFA-Basic

Entstanden sind diese Routinen zum Speichern und Laden von Feldern, weil sich mein sonst so schneller Computer beim Speichern des Feldes Feld% (249,249) wohl in eine Schildkröte verwandelt haben mußte.

Für Schreiben über PRINT# und Lesen über INPUT# brauchte er sage und schreibe:

speichern : 586,715 s = 9,47 min
laden : 514,665 s = 8,35 min

Was für meinen Geschmack deutlich zu lange war.

Doch da sollte sich etwas ändern. Beschäftigt man sich mit der Speicherverwaltung des ST, so erkennt man, daß die Felder sozusagen am Stück im Speicher vorliegen. Daraufhin meine Idee, das ganze Feld als Ganzes abzuspeichern und genauso wieder zu laden.

Zum Abspeichem benötigt man also die Startadresse (Start%) im Speicher und die Länge des Feldes (Lange%). Beides ist nicht all zu schwierig.

Die Startadresse läßt sich mit der Funktion Arrptr() feststellen, danach folgen nur noch die Tiefen der einzelnen Dimensionen, und direkt danach fängt das Feld an.

Die Länge ergibt sich, indem man die Tiefen der einzelnen Dimensionen und die Länge einer einzelnen Variablen miteinander multipliziert.

Das Laden vereinfacht sich durch das ganze noch mehr. Einfach mit Varptr(Feld%(0,0)) den Pointer auf die Startadresse des Feldes holen und dann das vorher gespeicherte Feld wieder direkt an die richtige Stelle im Speicher laden.

Messungen auf einer leeren Diskette ergaben für das obige Feld

speichern : 62,4 s ==> 9,4so schnell
laden : 27,2 s ==> 18,9
so schnell

Ganz beachtlich, oder etwa nicht?

Ein ganz netter Nebeneffekt trat auch noch auf. denn das Ganze braucht auf der Diskette auch nur noch 250kB statt der satten 4 lOkB mit denen das File vorher zu Buche schlug. Das entspricht einer Reduktion auf 60%.

Anpassung

Was muß ich jetzt jeweils für meine eigenen Bedürfnisse anpassen? Die Routine erkennt fast alles von selbst, man muß nur die Länge der jeweiligen Variablen anpassen. In der Routine ist dies schon vorgesehen. Man muß nur die richtige Zeile verwenden. Und sonst einfach den Variablennamen FELD% durch den eigenen Feldnamen ersetzen.

Und sonst: Ein Problem gab es bei der Sache doch noch, denn mit String Feldern funktioniert das ganze nämlich nicht. Der Grund liegt darin, daß die Strings nicht mit einer festgegebenen Länge abgelegt werden, sondern abhängig von der Länge der Strings.

Dim Feld%(249,249)
'
For I%=0 To 249 
    For J%=0 To 249 
        Feld%(J%, I%)=J%*100+I%
    Next J%
Next I%
'
Ti1=Timer 
Gosub Speichern 
Ti2=Timer
'
Ti3=Timer 
Gosub Laden 
Ti4=Timer
'
Print " ZEIT    :   NEU ALT"
Print "Speichern    : ";(Ti2-Ti1)/200;" s   586.715 s"
Print "Laden    : ";(Ti4-Ti3)/200;" s   514.665 s"

Procedure Speichern
    Local Byte%,Feldadr%,Anzahl%,Start%,Lange%,I%
    '
    ' Byte%=2   !   für X!
    Byte%=4     !   für X%
    ' Byte%=6   !   für X
    '
    Feldadr%=Lpeek(Arrptr(Feld%()))
    Anzahl%=Dpeek(Arrptr (Feld%())*4)
    Start%=Feldadr%+4*Anzahl%
    '
    Lange%=l
    For I%=1 To Anzahl%
        Mul Lange%,Lpeek(Feldadr%+4*Anzahl%-4*I%)
    Next I%
    Mul Lange%,Byte%
    '
    Bsave "DATEN.DAT", Start%, Lange%
    '
Return

Procedure Laden
    '
    Bload "DATEN.DAT",Varptr(Feld%(0,0))
    '
Return


Rolf Köhling


Links

Copyright-Bestimmungen: siehe Über diese Seite
Classic Computer Magazines
[ Join Now | Ring Hub | Random | << Prev | Next >> ]