 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
VersakhanIrenis
Anmeldungsdatum: 15.05.2010 Beiträge: 4
|
Verfasst am: 26.03.2011, 19:44 Titel: Quelltext zu langsam. Optimierungstips? |
|
|
Hallo.
Vor einiger Zeit bin ich mal über Seite mit Optimierungstips gestolpert, hab mir aber kein Lesezeichen gesetzt und finde sie jetzt, wo ich sie benötigen würde, nicht mehr. Alles was ich noch weiß ist das %-Variabeln schneller verarbeitet werden... Habt ihr eventuell Links oder Tips für mich?
Anbei die SUB die mir Probleme bereitet. Besonders Schritt#4 kostet unheimlich viel Zeit. Bin schon von PRINT auf POKE umgestiegen um Geschwindigkeit zu gewinnen und dank PCOPY hab ich es geschafft das der ruckelnde Aufbau des Bildes nicht sichtbar erfolgt, dafür stockt das Programm jetzt bei jedem Aufruf der SUB merkbar. (Also jedes mal wenn sich irgendetwas auf dem Bildschirm tut...) DOSBox muß ich auf mind. 5.000 Cylcles stellen damit es wieder flüssig läuft, ein Umstand den ich für ein reines ASCII-Programm eher nicht als optimal einsehe. *g*
Falls irgendetwas optimierbares ins Auge sticht bitte, bitte, bitte sagen
Danke
Code: | SUB Refresh.Screen
'Schritt#1: Herausfinden welcher Ausschnitt der Map angezeigt wird...
RSz% = 0
SELECT CASE PlayerX%
CASE 1 TO INT(BildHoehe% / 2)
FOR RSx% = 1 TO BildHoehe%
TempZeile$(RSx%) = LM.Zeile$(RSx%)
TempColZeile$(RSx%) = LM.Col.Zeile$(RSx%)
NEXT RSx%
CASE INT(BildHoehe% / 2) + 1 TO LM.Zeilen% - INT(BildHoehe% / 2) - 1
FOR RSx% = PlayerX% - INT(BildHoehe% / 2) TO PlayerX% + INT(BildHoehe% / 2) + 1
RSz% = RSz% + 1
TempZeile$(RSz%) = LM.Zeile$(RSx%)
TempColZeile$(RSz%) = LM.Col.Zeile$(RSx%)
NEXT RSx%
CASE LM.Zeilen% - INT(BildHoehe% / 2) TO LM.Zeilen%
FOR RSx% = LM.Zeilen% - BildHoehe% + 1 TO LM.Zeilen%
RSz% = RSz% + 1
TempZeile$(RSz%) = LM.Zeile$(RSx%)
TempColZeile$(RSz%) = LM.Col.Zeile$(RSx%)
NEXT RSx%
CASE ELSE: Errorcode 3, PlayerX%, "x"
END SELECT
SELECT CASE PlayerY%
CASE 1 TO INT(BildBreite% / 2)
FOR RSy% = 1 TO BildHoehe%
TempZeile$(RSy%) = MID$(TempZeile$(RSy%), 1, BildBreite%)
TempColZeile$(RSy%) = MID$(TempColZeile$(RSy%), 1, BildBreite% * 2)
NEXT RSy%
CASE INT(BildBreite% / 2) + 1 TO LEN(LM.Zeile$(1)) - INT(BildBreite% / 2)
FOR RSy% = 1 TO BildHoehe%
TempZeile$(RSy%) = MID$(TempZeile$(RSy%), PlayerY% - INT(BildBreite% / 2), BildBreite%)
TempColZeile$(RSy%) = MID$(TempColZeile$(RSy%), 2 * (PlayerY% - INT(BildBreite% / 2)) - 1, BildBreite% * 2)
NEXT RSy%
CASE LEN(LM.Zeile$(1)) - INT(BildBreite% / 2) + 1 TO LEN(LM.Zeile$(1))
FOR RSy% = 1 TO BildHoehe%
TempZeile$(RSy%) = MID$(TempZeile$(RSy%), LEN(TempZeile$(RSy%)) - BildBreite% + 1, BildBreite%)
TempColZeile$(RSy%) = MID$(TempColZeile$(RSy%), LEN(TempColZeile$(RSy%)) - BildBreite% * 2 + 1, BildBreite% * 2)
NEXT RSy%
CASE ELSE: Errorcode 4, PlayerY%, "x"
END SELECT
'Schritt#2: Player-Sprite einsetzen
RS.S2x% = Map.To.Screen.X(PlayerX%)
RS.S2y% = Map.To.Screen.Y(PlayerY%)
MID$(TempZeile$(RS.S2x%), RS.S2y%, 1) = CHR$(2)
MID$(TempColZeile$(RS.S2x%), RS.S2y% * 2 - 1, 2) = "15"
'Schritt#3: Schauen ob NPCs in der Map vorhanden sind.
FOR RSx% = 1 TO LM.Objekt.Anzahl%
SELECT CASE MID$(LM.Objekt.Typ$(RSx%), 1, 3)
CASE IS = "NPC"
RStempX% = Map.To.Screen.X(LM.Objekt.X%(RSx%))
RSTempY% = Map.To.Screen.Y(LM.Objekt.Y%(RSx%))
IF On.Screen.Check(LM.Objekt.X%(RSx%), LM.Objekt.Y%(RSx%)) = 1 THEN
MID$(TempZeile$(RStempX%), RSTempY%, 1) = CHR$(1)
MID$(TempColZeile$(RStempX%), RSTempY% * 2 - 1, 2) = "15"
END IF
CASE ELSE
END SELECT
NEXT RSx%
'Schritt#4: Alles den Bildschirm bringen...
SCREEN 0, , 0, 1
FOR RSx% = 1 TO BildHoehe%
'LOCATE LinksObenX% + RSx% - 1, LinksObenY%: PRINT TempZeile$(RSx%)
FOR RSy% = 1 TO LEN(TempZeile$(RSx%))
POKE ((LinksObenX% + RSx% - 1) * 160 - 161) + (LinksObenY% + RSy% - 1) * 2, VAL(MID$(TempColZeile$(RSx%), RSy% * 2 - 1, 2))
POKE ((LinksObenX% + RSx% - 1) * 160 + (LinksObenY% + RSy%) * 2 - 164), ASC(MID$(TempZeile$(RSx%), RSy%, 1))
NEXT RSy%
NEXT RSx%
PCOPY 0, 1
'Schritt#X+1: Debuginfos einblenden
IF Debug% = 1 THEN CALL Debug.Mode
END SUB |
|
|
Nach oben |
|
 |
XOR
Anmeldungsdatum: 23.07.2010 Beiträge: 161
|
Verfasst am: 26.03.2011, 20:10 Titel: |
|
|
mach statt "/" Integerdivision "\" diese sind schneller |
|
Nach oben |
|
 |
dreael Administrator

Anmeldungsdatum: 10.09.2004 Beiträge: 2529 Wohnort: Hofen SH (Schweiz)
|
Verfasst am: 27.03.2011, 14:57 Titel: |
|
|
Vielleicht wäre es noch sinnvoll, im Gesamt-Kontext zu erfahren, wofür Du das Ganze benötigst.
Da Du vermutlich im Textmodus eine Scrollgrafik realisieren möchtest: Eine ähnliche Situation hatte ich seinerzeit beim Rasterbike, wo ebenfalls gescrollt wird: Dort haben sich übrigens keinerlei Performance-Probleme selbst auf einem alten 386er gezeigt. Selbst im Interpreter-Modus hatte es dort immer noch flüssig funktioniert.
Sonst generelle Tipps:
- alles reine Integer-Arithmetik; also auch VAL() besser vermeiden, weil dies im Hintergrund ebenfalls über (langsame!) Fliesskommazahlen "kehrt".
- zweidimensonales Integer-Array anstelle von Strings verwenden, da Stringoperationen ebenfalls wegen der dynamischen Speicherverwaltung einiges an Rechenzeit verschlingen _________________ Teste die PC-Sicherheit mit www.sec-check.net |
|
Nach oben |
|
 |
VersakhanIrenis
Anmeldungsdatum: 15.05.2010 Beiträge: 4
|
Verfasst am: 27.03.2011, 19:03 Titel: |
|
|
Danke für die Antworten:
o) "\" funktioniert in QB auch? (Der Link führt zu einer FB-Seite)
o) Und Integer-Arithmetik klingt nach etwas das ich vllt. noch nachlesen sollte. Hab nächste Woche eh Nachtschicht... *g*
ad Gesamt-Kontext:
Hm, kurz gesagt soll es ein "Zelda-Clone in ASCII-Grafik" werden, also das mit der Scrollgrafik stimmt. Allerdings ist die nicht wirklich das Problem. Als ich "nur" Schwarz/Weiß zur Darstellung verwendet habe lief das Ganze eh flüssig. Erst als ich mir eingebildet habe auch die restlichen Nicht-Farben zu verwenden und die Zeilen nicht mehr komplett sondern Zeichen für Zeichen darzustellen wurde das Ganze (natürlich) langsamer. Im Endeffekt ist es also nur Schritt#4 dieser SUB der alles runterbremst.
Ändert man den Code wieder auf den ursprünglichen Zustand um paßt nämlich eh wieder alles.
Code: | 'Schritt#4: Alles den Bildschirm bringen...
SCREEN 0, , 0, 1
FOR RSx% = 1 TO BildHoehe%
LOCATE LinksObenX% + RSx% - 1, LinksObenY%: PRINT TempZeile$(RSx%)
'FOR RSy% = 1 TO LEN(TempZeile$(RSx%))
'POKE ((LinksObenX% + RSx% - 1) * 160 - 161) + (LinksObenY% + RSy% - 1) * 2, VAL(MID$(TempColZeile$(RSx%), RSy% * 2 - 1, 2))
'POKE ((LinksObenX% + RSx% - 1) * 160 + (LinksObenY% + RSy%) * 2 - 164), ASC(MID$(TempZeile$(RSx%), RSy%, 1))
'NEXT RSy%
NEXT RSx%
PCOPY 0, 1 |
Hier noch die aktuelle .BAS (Link) |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 27.03.2011, 20:14 Titel: |
|
|
VersakhanIrenis hat Folgendes geschrieben: | o) "\" funktioniert in QB auch? (Der Link führt zu einer FB-Seite)
o) Und Integer-Arithmetik klingt nach etwas das ich vllt. noch nachlesen sollte. Hab nächste Woche eh Nachtschicht... *g* |
zu 1) ja; wie dem Link zu entnehmen ist, gibt es unter QB nur nicht den kombinierten Operator a \= 2, aber die Integerdivision ansonsten schon.
Integerdivision bedeutet ganz einfach, dass bei der Division nur mit Ganzzahlen gerechnet wird; dementsprechend ist es auch schneller. Wenn das Ergebnis sowieso ein Integer sein soll, dann ist das durchaus zu empfehlen. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|