Beiträge von JeeK im Thema „Pixel über Array statt Poke setzen“

    Stimmt, ich unterschätze das Parsen des Interpreters, Compiler versauen einen in der Beziehung :whistling:

    Hab' mal beides auf Variablen umgestellt - a%(i)=i% und pokea,i. Dann ist Array max. 25% schneller. Spannend ist der Unterschied bei den verschiedenen i% Werten.

    Bei i% scheint es umso länger zu daueren, je mehr bits gesetzt sind und umso höherwertiger sie sind. -1 dauert am längsten (klar alle Bits gesetzt). Bei den einzelnen Bits: 16384 am Kürzesten. 8192 dauert einen kleinen Hauch länger... usw usf. bis 1 (bei meinem Programm sind es jeweils 5 TI-Einheiten). Nur -32768 schlägt aus der Reihe, das braucht ungefähr solange wie 2048. Och nöööö... wenn ich einem INTEGER-Array eine Fließkommazahl zuweise ist er in der Regel schneller als bei einer INTEGER-Zahl. Das hat dann aber nichts mehr mit Interpreter vs. Compiler zu tun, sondern dass Basic V2 schräg ist.

    Aber der Vorteil schrumpft deutlich und wenn die Auslese und Oder-Verknüpfungen bei Ganzzahlen ähnlich schleichen wie der zum setzen wundert mich gar nix mehr.


    Das Integer immer mit Floats gerechnet werden hat ja Mike schon ausführlich erklärt. Vielleicht ergänzend zu oben: Die Variation in der Zeit bei unterschiedlichen Werten kommt wohl von der Konvertierung Integer-Float. Eigentlich eine relativ einfache Operation, aber da die Float im "normalisierten" Format sind, fallen dann bei der Mantissennormalisierung, d.h. die gesamte Mantisse (4 Bytes) muss iterativ mit Schiebeoperationen so oft verschoben werden, bis das höchstwertige Bit quasi ganz "links" ist. D.h. z.B. -1 (bei Float ist das Vorzeichen extra) ergäbe das dann 1, also %0000 0000 0000 0001 und dieses eine Bit muss dann ganz nach links wandern. Die Trivialoptimierung, Nullbytes der Mantisse (rechts davon) nicht mitzuverschieben, verringert den Aufwand nur marginal. Das also bei Integer zu Float. Ähnliches Spielchen dann in die andere Richtung. ;)
    Das ist aber keine Besonderheit von BASIC V2, das wäre bei allen Interpretern so, die die Zahlen so darstellen, wenn man mal davon absieht, dass V2 hier generell nur mit Float rechnet (das war aber wirklich dem Platzmangel im ROM geschuldet - beim BASIC 3.5 oder 7.0 hat man sich dann auch nicht mehr getraut Bewährtes gravierend umzuschreiben und wohl eher auf neue Kommandos Wert gelegt).

    Die Idee beschäftigte mich schon vor Urzeiten, als das erste Mal das Thema Löschen mit Array aufkam. Außerdem hatte sich bei mir irgendwie festgesetzt, dass die Implementierung des Poke-Befehls ineffizient sein soll (hab' ich aber nie überprüft). Von daher musste ich das einfach mal ausprobieren...

    Die Modifikationen bringen etwas, allerdings auch beim Ausgangsprogramm - das leider so schon nen kleinen Tick schneller ist.

    Was mich fuchst - eigentlich ist das Array *deutlich* schneller:
    [..]
    Hmmm...


    Der Vergleich ist nicht ganz fair. POKE ist so primitiv, sowas kann man gar nicht ineffizient im Interpreter machen. Das Problem ist die 2x die Ausdruckauswertung für die Parameter. Im Speziellen das "255". Das Parsing baut einen Float-Wert zusammen und für jede weitere Ziffer (bezogen auf eine einstellige Zahl) fällt eine Float-Multiplikation mit 10 an. Das kostet. Und natürlich hat ja die POKE-Variante ja den doppelten Schleifen-Overhead.

    Wenn der POKE-Wert (aber auch bei der Array-Variante) in einer Variable ist, ist eine Art Waffengleichheit gegeben: in beiden Fällen muss 2* in der Variablen-Tabelle gesucht werden (Index, Wert). Bei der Arrayvariante dann aber auch noch in der separaten Array-Tabelle und das Feldelement muss berechnet werden (sind immerhin auch in 16-Bit-Arithmetik durchgeführte Multiplikationen, zumindest eine, glaub ich).

    Im obigen Beispiel braucht die Array-Variante 50 % von der POKE-Variante.
    Wenn man das mit Variablen macht, denn reduziert sich der Vorsprung nur noch auf 70 % Reduktion. D.h. POKE ist an sich schneller, d.h. der Array-Zugriff ist an sich aufwändiger (Feldelement berechnen, mehr BASIC-Text zu parsen).

    Sehr gute Idee, das mit dem Integer-Array! :thumbsup:

    Bisserl Herumfeilen geht vielleicht noch:
    Statt
    29 ad=li(yp)+int(xp/z8)*z4:f%(ad)=f%(ad)orbi%(xpandz7,ypandz1):return

    29 ad=li(yp)+(xpandm7)/z2:f%(ad)=f%(ad)orbi(xpandz7,ypandz1):return

    Wobei z1, aber auch z7 (geht gerade noch) viel früher angelegt werden sollten (unter den ersten 10 Variablen).
    bi() als Integer-Array bringt nichts, außer Platz, der aber bei 14 Elementen auch nicht das Kraut fett macht.
    Im Gegenteil, das Parsing von "%" und die Konvertierung Integer-Float kostet auch noch Zeit (1,5 %).
    In Summe bewegt sich die Ersparnis (nicht Gesamtlaufzeit, nur bezogen auf diese Zeile) dann bei knapp 3,5 %.

    Wie schon vorher angemerkt bringt das Wegoptimieren des GOSUB-RETURN freilich noch viel mehr. ;)