Management von Global-Variablen?

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

 

PacMani

Betreff: Management von Global-Variablen?

BeitragMo, Dez 21, 2009 19:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Blitz3D ist ja ganz unbestritten 'ne super 3D-Spielprogrammiersprache. Nur diese Variablenverwaltung regt mich ein wenig auf, weil ich nicht weiß, wie ich damit umgehen soll.
Ich lade zum Beispiel ein Level innerhalb einer Funktion, erstelle dort auch die Spielerobjekte, die innerhalb des ganzen Programms verwendet werden, bearbeite sie dort etc., dann wird die Funktion wieder verlassen. Um nun aber diese in der Funktion deklarierten Variablen woanders zu nutzen, muss ich sie immer erst als Global deklarieren - das klappt aber nur im Hauptprogramm und nicht in den Funktionen. Sogesehen muss mein Programm ja immer so aussehen:

# Globale Deklarierung der Variablen ohne Initialisierung
# Funktion zum Laden des Levels
## Initialisieren und Bearbeiten dieser Variablen innerhalb der Funktion
# EIne andere Funktion
## Hier werden diese Variablen wieder bearbeitet

Was mich nun stört ist das sinnlose globale Rumdeklarieren am Anfang meines Programms >:/ Da stehen dann mehrere Zeilen von "Global Bopp; Global Bapp; Global Sowieso" etc., nur damit ich sie auch bloß überall verwenden kann. Gibt es da nicht eine Variante die sexier ist?

robotx

BeitragMo, Dez 21, 2009 19:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Hierzu bieten sich Types wunderbar an: Type
www.botbomb.robotzgames.de
www.robotzgames.de

Nicdel

BeitragMo, Dez 21, 2009 19:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Auch nutzbar sind BlitzArrays, die als Parameter übergeben werden und mit Return wieder zurückgeholt werden können.
Desktop: Intel Pentium 4 2650 Mhz, 2 GB RAM, ATI Radeon HD 3850 512 MB, Windows XP
Notebook: Intel Core i7 720 QM 1.6 Ghz, 4 GB DDR3 RAM, nVidia 230M GT, Windows 7
 

PacMani

BeitragMo, Dez 21, 2009 19:48
Antworten mit Zitat
Benutzer-Profile anzeigen
robotx hat Folgendes geschrieben:
Hierzu bieten sich Types wunderbar an: Type

Ja, aber wenn ich nur ein Objekt dieses Typs brauche, z.B. das Spielerobjekt unter "Player", ein Sky-Mesh unter "Sky", Wasser unter "Water" und ein 3D-Modell des Levels unter "Level"? Kann ich da mit Types auch gut arbeiten oder sind die Unterschiede zwischen diesen Objekten doch zu groß?

Nicdel hat Folgendes geschrieben:
Auch nutzbar sind BlitzArrays, die als Parameter übergeben werden und mit Return wieder zurückgeholt werden können.

Wie würde dann mein Programm in Art des "Schemas" oben aussehen?

Nicdel

BeitragMo, Dez 21, 2009 19:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Na ja, es ist glaube ich keine richtige Verbesserung. Vergiss einfach das mit den Arrays Very Happy
Desktop: Intel Pentium 4 2650 Mhz, 2 GB RAM, ATI Radeon HD 3850 512 MB, Windows XP
Notebook: Intel Core i7 720 QM 1.6 Ghz, 4 GB DDR3 RAM, nVidia 230M GT, Windows 7

Midimaster

BeitragMo, Dez 21, 2009 19:53
Antworten mit Zitat
Benutzer-Profile anzeigen
gelöscht...

(sorry, war quatsch)
  • Zuletzt bearbeitet von Midimaster am Mo, Dez 21, 2009 19:56, insgesamt 2-mal bearbeitet
 

PacMani

BeitragMo, Dez 21, 2009 19:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Auslagern in eine Datei hatte ich auch erst in Erwägung gezogen, habe nur Angst dass ich die dann nach und nach zu voll proppe, dem Speicherverbrauch macht das doch nicht mehr so viel aus wie früher, oder?

Habe mein Spiel z.B. so aufgebaut
-> Initalisierung "GameInit.bb"
-> Menü "GameMenu.bb"
-> Spiel "GameGame.bb" (xD)

Sollte ich dann bei Initialisierung gleich ein "Include "GameVars.bb"" einfügen, sodass sie das ganze Spiel über verfügbar sind, oder das häpchenweise aufteilen, da ich ja auch manchmal globale Soundvariablen lade (die ja nicht gerade klein sind)?

Midimaster

BeitragMo, Dez 21, 2009 20:13
Antworten mit Zitat
Benutzer-Profile anzeigen
war vorhin vielleicht doch kein Quatsch....

Deshalb jetzt doch nochmal:

Das Include "Variablen.BB" schafft optische Ordung im Script. Es hat überhaupt keinen Einfluss auf Performance oder Speicherverbrauch. Egal, wo Du eine GLOBAL -Variable hinschreibst... sie wird vom Compiler im fertigen Programm sofort zu Beginn angelegt.

Also Aufteilen in Häppchen oder in eine Datei ist völlig egal.

Das komplette Anlegen der GLOBALs verbraucht aber auch nicht wirklich Speicher, es sind ja zunächst nur Zeiger. Erst wenn Du sie mit Inhalten füllst, z.b. Bild=LoadImage, geht dafür Speicher drauf.

Aber auch hier brauchst Du Dir, außer bei megagroßen Bildern oder megalangen Sounds, keine Gedanken zu machen. Ich lade fast immer alle Bilder und Sounds am Anfang meiner Programme.

Mit Megagroß meine ich Bilder von über 1000x1000 Pix (= 3MB) oder Sounds von 1 Minute Länge (=12MB)
  • Zuletzt bearbeitet von Midimaster am Mo, Dez 21, 2009 20:18, insgesamt einmal bearbeitet
 

PacMani

BeitragMo, Dez 21, 2009 20:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Achso gut! Danke Smile dann "globalisiere" ich die SoundVariablen also schon anfangs, aber initialisiere sie erst wenn sie gebraucht werden Very Happy
 

Kruemelator

BeitragMo, Dez 21, 2009 20:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe zu Beginn auch sehr viele globale Variablen. Aber dadurch gibt es eigendlich keine Nachteile. Wenn es dich am Anfang stört dann packe sie in eine andere .bb-Datei und benutze include, oder springe mit goto ans Ende des Codes und wieder zurück wenn du sie lieber da hättest. Du kannst auch mehrere Arrays genutzen, sind ja auch immer Global. Dann für die einzelnen Variablentypen ein extra Array.
Code: [AUSKLAPPEN]
Dim vari%(9)
Dim varf#(9)
Dim vars$(9)

Dann musst du dir aber immer merken welcher Eintrag welche Nummer hat.

Xeres

Moderator

BeitragMo, Dez 21, 2009 20:22
Antworten mit Zitat
Benutzer-Profile anzeigen
oder springe mit goto ans Ende des Codes und wieder zurück wenn du sie lieber da hättest.
Solchen Unsinn sollte man nicht mal im Spaß Vorschlagen Rolling Eyes
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

blackgecko

BeitragMo, Dez 21, 2009 23:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Pac-Man hat Folgendes geschrieben:
Da stehen dann mehrere Zeilen von "Global Bopp; Global Bapp; Global Sowieso"

Das lässt sich auch schreiben:
Code: [AUSKLAPPEN]
Global Bopp,Bapp,Sowieso
So long and thanks for all the fish.
Fedora 17 | Windows 7 || BlitzPlus | BlitzMax
Rechtschreibflame GO!!! Deppenapostroph | SeidSeit | Deppenakzent | DassDas | Deppenleerzeichen | TodTot | enzigste.info - Ja, ich sammel die.
 

Cyderic

BeitragDi, Dez 22, 2009 10:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Es ist aber sicher nicht sinnvoll einfach stumpfsinnig alles zu Globalisieren oder? Ich könnte mir vorstellen das es viel mehr Speicher braucht. Mein Lehrer sagte mal, das globale Variablen einfach zu "hacken" wären. Also man könnte sie einfacher im Speicher finden usw
Native ITler

Midimaster

BeitragDi, Dez 22, 2009 10:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Alles GLOBAL zu machen ist heutzutage vom Speicherbedarf oder der Performance* eigentlich kein Problem, aber...

Heute geht es mehr um die Lesbarkeit, Verständlichkeit oder Nachbearbeitkeit eines Codes. Ein ebenso wichtiger Aspekt ist die Möglichkeit einmal erstellte Routinen in anderen Programmen wiederzunutzen.

Und ganz wichtig: Mit lokalen Variablen hat man deutlich weniger Fehler im Code als mit Globalen.

Hierzu das erste Beispiel:

Hier wird scheinbar berechnet, wie of man A mit sich selbst multiplizieren muss, bis 10000 rauskommt
Code: [AUSKLAPPEN]
;*** Hinweis: negatives Beispiel! So nicht nachmachen! ***
Global A%,I%,Stern$
a=2
Repeat
  a=a*a
  i=i+1
Until a>10000

SternchenMalen
Print "A  wurde " + i " mal multipliziert bis 10000 herauskam"
SterchenMalen

Function SterchenMalen()

    for i=0 to 79
         Stern=Stern + "*"
    Next
    Print Stern
End function


hier setzt die Funktion SternchenMalen I immer auf 80, und weil Global auch im Hauptprogramm.


Es ist auch keine große Arbeit, darübernachzudenken, ob eine Variable LOKAL oder GLOBAL werden soll.

Faustregel:
Alle Variablen, die im Spiel an mehreren Stellen von Bedeutung sind, sind GLOBAL: Punktestand, Spielerkoordinaten, Zustände, etc..
Alle Variablen, die nur Zwischenergebnisse sind, um eine ganz andere Variable zu berechnen, sind LOKAL

Mein Liebling-Beispiel prüft, ob eine Zahl innerhalb vorgegebener Grenzen bleibt, beläßt sie, wenn es so ist, oder setzt sie auf den Grenzwert, wenn die Zahl zu groß oder zu klein war. Hier, finde ich, zeigt sich der große Vorteil von Funktionen:

Code: [AUSKLAPPEN]
Global A%
A=Rand(0,1000)
A=ZahlZwischen(A,122,156)

Funktion ZahlZwischen%(SuchZahl%,Min%,Max%)
    Local Ergebnis%

    If SuchZahl>Max then
        Ergebnis=Max
    ElseIf SuchZahl<Min Then
        Ergebnis=Min
    Else
        Ergebnis=SuchZahl
    Endif

    Return Ergebnis
End Function


Hier siehst Du nun wirklich alle Vorteile lokaler Variablen. Anmerkung: Neben den LOKAL definierten Variablen (Ergebnis) sind ja auch immer die Variablen im Funktionsheader LOKAL (SuchZahl, Min,Max).

In der Funktion kommen Variablennamen wie MAX vor, es ist gut möglich, dass eine Variable gleichen Namens im Hauptprogramm existiert. Stört aber nicht, denn das MAX der Funktion is ja LOKAL. Durch diese freie Wahl der Variablennamen kann ich Dir die Funktion so schreiben, das sie sich schon fast von selbst erklärt und Du kannst sie sofort in Deinen Programmen nutzen, ohne dass sie irgendeine negative Auswirkung auf das Hauptprogramm hätte.


*) PERFORMANCE !!!!

Bei kleinen Routinen, die du 1x rufst, die dann nur kurz abgearbeitet werden, wirst Du keinen Performance-Gewinn bemerken. Wenn aber Variable LOKAL sind, werden sie nicht nach jeder Benutzung in das RAM geschrieben, sondern in den schnellen Speicher direkt im Chip oder bleiben sogar gleich im Register. Und das geht ca 10x bis 1000x schneller!!! Dies kann man übrigens nicht in der IDE+DEBUGGER prüfen, weil hier immer alles in den RAM geschrieben werden muss. Aber in der fertigen EXE geht es dann ab!!!

So wird eine...
Code: [AUSKLAPPEN]
Function BloedSinn#()
    Local Ergebnis#

    For Local I%=0 to 100000
        Local B#, C#
        B=I*2+C
        C=B/100
        Ergebnis=sqr(B*C)
    Next

    Return Ergebnis
End Function

...superfix, weil die LOKALEN I, B, C, aber auch 100000, 2 und 100 wahrscheinlich direkt auf den Prozessor-Registern bleiben, während ERGEBNIS im schneller RAM oder STACK des Chips landet.
  • Zuletzt bearbeitet von Midimaster am Di, Dez 22, 2009 15:14, insgesamt 3-mal bearbeitet

Jamagin

Betreff: global - lokal

BeitragDi, Dez 22, 2009 11:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Bevor man ein Projekt beginnt, sollte man ein Konzept ausarbeiten!
Und wer viele globale Variablen braucht der schreibt sich halt in Excel eine Variablenliste, somit bewahrt man auch in größeren Projekten den Überblick was welche Variable im Programm tut. Wer das nicht will ist schlichtweg einfach zu faul!! Shocked

Will niemanden angreifen aber wie Midimaster schon sagte, ein Programm sollte stets sauber und ordentlich strukturiert bzw. auch mit Kommentaren versehen sein, denn wenn man zB. längere Zeit nicht an seinem Projekt arbeitet, findet man sich auf jeden Fall wieder schneller ins Projekt rein als das man wieder suchen muß, was macht diese Variable oder was macht jene Variable.

Ich schreibe mir immer eine Variablenliste und kommentiere das auch. Natürlich geht da ein wenig Zeit drauf, doch je besser die Vorarbeit eines Projektes umso eher stellt sich auch der gewünschte Erfolg ein!

Und wer keine globalen Variablen mag, der nimmt halt lokale Variablen in den Funktionen, muß man halt immer Werte übergeben.

lg. Jamagin Cool
Bevor du etwas neues beginnst, erledige das alte

Midimaster

BeitragDi, Dez 22, 2009 11:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich bin ja der festen Überzeugung das der Variablennamen selbst die beste Kommentierung ist. Daher halte ich nichts von bescheibenden Listen oder Kommentaren hinter den Variablen. Meine Variablen heißen deshalb oft so:

WindVonRechtsStaerke

SpielerName

KleinerBaumBild

ExplosionsSound

locBild (wenn dieses Bild nur local benötigt wird)

Die Länge der Variablennamen hat übrigens keinen Einfluß auf die Geschwindigkeit des Spieles. Der Compiler ersetzt jeden Namen sowieso durch eine Zahl (Zeiger)

Jamagin

BeitragDi, Dez 22, 2009 11:37
Antworten mit Zitat
Benutzer-Profile anzeigen
@midimaster

Du magst schon Recht haben, doch zeig mir den der sich Hunderte globale Variablen im Kopf behält und auch weiß wo überall im Programm diese dann stehen bzw. wo was zugewiesen wird.

Bei Kleinprojekten, klar ist sowas egal und natürlich ich benenne meine Variablen auch nach ihrem Wirken, sind manchmal sehr witzige Wörter dabei!

lg. Jamagin Cool
Bevor du etwas neues beginnst, erledige das alte

Hip Teen

BeitragDi, Dez 22, 2009 15:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Midimaster, ich seh irgendwie nicht den Grund an manchen Stellen, warum du die Variable Global setzt.
Zum Beispiel bei deinem ersten Beispiel. Wenn du I lokal definierst, SternchenMalen die Anzahl als Rückgabewert hat und du diesen I zuordnest, funktioniert alles einwandfrei.
Oder bei deinem 2. Beispiel, warum ist A Global?
Die Beispiele zeigen gerade nicht, wie man Local und Global richtig einsetzt.
Spruch der Woche: "Ahh, ein neues Gesicht?!" - "Nein, das hab ich schon länger"

Midimaster

BeitragDi, Dez 22, 2009 15:11
Antworten mit Zitat
Benutzer-Profile anzeigen
@Hip Teen

mann ej... Rolling Eyes Die Frage des Fragenden war es doch: "Spricht etwas dagegen, gleich alles GLOBAL zu machen?"

Und meine Antwort lautet "Ja, denn....siehe schlechtes Beispiel"

Vielleicht sollte ich das schlechte Beispiel noch als schlechtes Beispiel kennzeichnen! Du hast recht!

Noobody

BeitragDi, Dez 22, 2009 15:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Midimaster hat Folgendes geschrieben:
Bei kleinen Routinen, die du 1x rufst, die dann nur kurz abgearbeitet werden, wirst Du keinen Performance-Gewinn bemerken. Wenn aber Variable LOKAL sind, werden sie nicht nach jeder Benutzung in das RAM geschrieben, sondern in den schnellen Speicher direkt im Chip oder bleiben sogar gleich im Register. Und das geht ca 10x bis 1000x schneller!!!

Nein. Vergleiche mal die beiden Codes:

BlitzBasic: [AUSKLAPPEN]
Print "Local:"

Local Counter = MilliSecs()
BloedSinn()
Print ( MilliSecs() - Counter ) + " ms"

WaitKey
End

Function BloedSinn#()
Local Ergebnis#

For I=0 To 10000000
Local B#, C#
B=I*2+C
C=B/100
Ergebnis=Sqr(B*C)
Next

Return Ergebnis
End Function


BlitzBasic: [AUSKLAPPEN]
Print "Global: "

Global Ergebnis#, I, B#, C#

Local Counter = MilliSecs()
BloedSinn()
Print ( MilliSecs() - Counter ) + " ms"

WaitKey
End

Function BloedSinn#()
For I=0 To 10000000
B=I*2+C
C=B/100
Ergebnis=Sqr(B*C)
Next

Return Ergebnis
End Function


Bei mir sind beide Versionen exakt gleich schnell - von den 10x bis 1000x nichts zu merken. Ob eine Variable global oder lokal ist, hat überhaupt keinen Einfluss, ob sie in einem Register gespeichert wird oder nicht. Ein halbwegs intelligenter Compiler steckt sehr oft verwendete Variablen, z.B. Schleifenzähler, unabhängig von ihrem Gültigkeitsbereich in Register, falls möglich; wobei ich bezweifle, dass der BB-Compiler das überhaupt macht Razz

Midimaster hat Folgendes geschrieben:
Dies kann man übrigens nicht in der IDE+DEBUGGER prüfen, weil hier immer alles in den RAM geschrieben werden muss. Aber in der fertigen EXE geht es dann ab!!!

Das kann nicht sein, da die IDE beim kompilieren eine temporäre Exe erstellt, die -exakt- mit der durch 'Create Executable' kreierten übereinstimmt.
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group