Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Quelltext zu langsam. Optimierungstips?

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu QBasic.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
VersakhanIrenis



Anmeldungsdatum: 15.05.2010
Beiträge: 4

BeitragVerfasst am: 26.03.2011, 19:44    Titel: Quelltext zu langsam. Optimierungstips? Antworten mit Zitat

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 lächeln
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
Benutzer-Profile anzeigen Private Nachricht senden
XOR



Anmeldungsdatum: 23.07.2010
Beiträge: 161

BeitragVerfasst am: 26.03.2011, 20:10    Titel: Antworten mit Zitat

mach statt "/" Integerdivision "\" diese sind schneller
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
dreael
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 2529
Wohnort: Hofen SH (Schweiz)

BeitragVerfasst am: 27.03.2011, 14:57    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
VersakhanIrenis



Anmeldungsdatum: 15.05.2010
Beiträge: 4

BeitragVerfasst am: 27.03.2011, 19:03    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4704
Wohnort: ~/

BeitragVerfasst am: 27.03.2011, 20:14    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu QBasic. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
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.

 Impressum :: Datenschutz