Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
Bisher habe ich mit char Arrays gearbeitet, allerdings sind sie statisch und verbrauchen deshalb mehr Speicher als eigentlich benötigt wird.
Gibt es eine Möglichkeit char Arrays zu vergrößern oder zu verkleinern oder MUSS ich Pointer benutzen?
[...] und versuche lokale Variablen so gut wie es geht zu vermeiden, da sie für mich in den meisten Fällen nur unnötigen Speicherverbrauch darstellen.
(Nebenbei am Rande, gibt es eine Möglichkeit Variablen in Strukturen gleich bei der Deklarierung einen Wert zuzuweisen, sodass ich nicht auf "Initalisierungsfunktionen" zurück greifen muss?)
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 |
struct blub { int a; float b; }; // ... blub b = { 42, 3.14f }; |
Ich weiß auch nicht ob es so eine gute Idee ist auf reines C zurück zu greifen, ich selber brauche den objekt-orientierten Kram nicht aber ich weiß nicht ob einige Bibliotheken ihn brauchen, auch wird oft davon abgeraten reines C zu benutzen.
Wie auch immer, ich würde gerne mit einfachen Funktionen wie fprintf, strcpy, etc. arbeiten, denn ich finde die typischen C++ Funktionen auch sehr kryptisch in ihrem Gebrauch, sie bringen mir nichts, schränken dafür aber die Lesbarkeit von meinem eigenen Code meiner Meinung nach ein.
Edit: Vektoren brauchen C++, ohne die ist Schluss mit dynamischen arrays. o;
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »dot« (29.06.2012, 16:38)
Nicht ganz, ich habe von Anfang an versucht mir eine vernünftige, effektive Art und Weise des Programmierens anzueignen, wenn ich das schon sehe wie groß manche Executables von Computerspielen sind, wird mir schlecht und dann wird auch meistens extrem viel RAM alloktiert, ganz einfach weil z.B. ein paar Leute zu Faul waren darauf zu achten ob sie Variablen benutzen die nur ein Byte groß sind oder ganze vier oder darauf zu achten ob man irgendwo noch Variablen einsparen kann, ohne, dass dies auf Kosten der Rechenzeit geschieht. Irgendwann rechnet sich das natürlich, bei sehr großen Arrays oder einer riesigen Menge von Variablen. Sieh dir mal Programme wie kkrieger an, die arbeiten wirklich effektiv zumindest was Festplattenspeicher angeht und auch wenn das natürlich auf die Rechenzeit schlägt aber es hat großes Potential und es gibt mit Sicherheit ähnliche Einsparungsmöglichkeiten was RAM und Rechenzeit betrifft. Wenn ich könnte würde ich sogar alles in Assembler machen, ich bin in dieser hinsicht eher ein Perfektionist auch wenn mich das Zeit kostet, ich verpöne so einen Stil eben, so wie andere Leute eben vielleicht einen anderen Stil verpönen.Mir scheint du hast da irgendwo was falsch verstanden. Wieso genau sind die deiner Meinung nach "unnötiger Speicherverbrauch". Abgesehen davon, hab ich generell den Eindruck, dass du dir viel zu viele unnötige Gedanken um den Speicherverbrauch machst. Speicherverbrauch ist sicherlich nicht unwichtig, aber besonders hier vermutlich vollkommen irrelevant. Da sind andere Dinge wesentlich wichtiger für die Performance...
Oha, das kann ich leider nicht so benutzen, so verschachtelt wie meine Strukturen sind.Ja
C-/C++-Quelltext
1 2 3 4 5 6 7 8 9 struct blub { int a; float b; }; // ... blub b = { 42, 3.14f };
C++ ist wesentlich mehr als "objektorientierter Kram". C++ bietet schon auch allein für prozedurale Programmierung extrem viele Vorteile. Der einzige vernünftige Grund, C zu benutzen, ist, wenn es für eine Zielplattform keinen brauchbaren C++ Compiler gibt...
Nicht ganz, ich habe von Anfang an versucht mir eine vernünftige, effektive Art und Weise des Programmierens anzueignen, wenn ich das schon sehe wie groß manche Executables von Computerspielen sind, wird mir schlecht und dann wird auch meistens extrem viel RAM alloktiert, ganz einfach weil z.B. ein paar Leute zu Faul waren darauf zu achten ob sie Variablen benutzen die nur ein Byte groß sind oder ganze vier oder darauf zu achten ob man irgendwo noch Variablen einsparen kann, ohne, dass dies auf Kosten der Rechenzeit geschieht. Irgendwann rechnet sich das natürlich, bei sehr großen Arrays oder einer riesigen Menge von Variablen. Sieh dir mal Programme wie kkrieger an, die arbeiten wirklich effektiv zumindest was Festplattenspeicher angeht und auch wenn das natürlich auf die Rechenzeit schlägt aber es hat großes Potential und es gibt mit Sicherheit ähnliche Einsparungsmöglichkeiten was RAM und Rechenzeit betrifft. Wenn ich könnte würde ich sogar alles in Assembler machen, ich bin in dieser hinsicht eher ein Perfektionist auch wenn mich das Zeit kostet, ich verpöne so einen Stil eben, so wie andere Leute eben vielleicht einen anderen Stil verpönen.Mir scheint du hast da irgendwo was falsch verstanden. Wieso genau sind die deiner Meinung nach "unnötiger Speicherverbrauch". Abgesehen davon, hab ich generell den Eindruck, dass du dir viel zu viele unnötige Gedanken um den Speicherverbrauch machst. Speicherverbrauch ist sicherlich nicht unwichtig, aber besonders hier vermutlich vollkommen irrelevant. Da sind andere Dinge wesentlich wichtiger für die Performance...
Soweit ich weiß sorgen aber Datentypen wie z.B. int32_t dafür, dass ich wirklich einen signed integer habe der 4 byte groß ist. Ich kann mein Programm immernoch schön strukturieren und robust programmieren, auch wenn ich diese Einsparungen vornehme.Möglichst kleine exe-Dateien zu erstellen ist eher eine sportliche Disziplin und in der Realität nur für Virenprogrammierer interessant. Ob deine exe jetzt 20kb hat oder 5mb, macht doch bei heutigen Festplatten überhaupt keinen Unterschied mehr.
Zum Thema kleine Variablen hatten wir hier neulich einen netten Thread. Kurz gesagt ist es wahrscheinlich, dass der Compiler aus Gründen der Zugriffszeit trotzdem alles an 4 Byte ausrichtet und du letztendlich überhaupt nichts sparst. Ich bin eher dafür, robuste und schön strukturierte Programme zu schreiben, anstatt mich an Optimierungen von zweifelhaften Nutzen aufzuhalten.
In C++11 kann man Werte auch direkt zuweisen:
http://en.wikipedia.org/wiki/C%2B%2B11#O…ion_improvement (member initialization Beispiel)
Da ich selber nur als Hobby Spiele programmiere, habe ich in der Tat ein unendliches Zeitbudget, daher entfällt dieses Argument auch. Allerdings muss ich sagen, dass der Vergleich nicht wirklich gut ist, immerhin sprach ich hier von Datentypen und lokalen Variablen. Das es mit Assembler nicht wirklich funktioniert, das ist mir klar, immerhin bin ich aber auch da abhängig von Bibliotheken und da dort viel von der Rechenzeit abfällt und es so gut wie garkeine Tutorials oder Hilfen gibt lohnt es sich nicht. Hinzu kommt noch, dass zusammen mit Windows ein äußerst hässlicher Macroassembler entsteht der wesentlich unübersichtlicher ist als konventioneller Assembler oder C/C++.Was Performance allgemein angeht, muss ich aber sagen, es macht mehr Sinn sein Programm möglichst effizient (in Codingzeit) und übersichtlich fehlerfrei hinzuschreiben und sich dann mit einem Profiler anzusehen welche Stellen wirklich Performancekritisch sind und diese dann zu optimieren. Ein etwas überzeichnetes Beispiel: Es macht keinen Sinn auf Teufel komm raus eine Sortierfunktion in Assembler zu entwickeln wenn man dann nur einen Bubblesort hinbekommt, während der C Entwickler in der selben Zeit einen Quicksort implementiert. Der Quicksort in C spielt den Bubblesort in Assembler natürlich locker an die Wand.
Für Programmcode gilt typischerweise die 80-20 Regel: 80% der Zeit werden in 20% des Codes verbracht. D.h. wenn du wirklich 100% deines Codes so programmierst, muss ich dir leider sagen das du eine Menge Zeit verschwendest Code optimal zu halten der sich nachher gar nicht wirklich auf die Performance auswirkt - Zeit die dir bei den wichtigen 20% dann fehlt. Ausser natürlich, du hast ein unendliches Zeitbudget, dann kann es natürlich keine Zeit geben die dir fehlt. Aber sowas hat man selten.
Jep, beim Programmieren als Hobby hat man das unendliche Zeitbudget noch am ehesten, es ist ja nur begrenzt durch die eigene Geduld (und eigene Lebenserwartung). Bei einem Job würde dir das dann aber (zurecht) um die Ohren gehauen werden, denn da musst du irgendwann überhaupt fertig werden und wenn du Zeit hast zum optimieren, dann bekommen die wichtigen Stellen natürlich Priorität. Das heißt aber nicht sofort, dass die Programmierer einfach faul sind! Das war eben schon eine ziemlich böse Unterstellung von dir!
Und was Jonathan meinte: Eine Struct aus zwei Shorts muss nicht unbedingt weniger Platz benutzen als eine Struct aus einem Long und einem Short. CPUs kommen schlecht mit Addressen zurecht die nicht durch vier teilbar sind, deswegen wird der Compiler selbstständig einen kleinen Pufferbereich einschieben, damit der zweite Short auch bei einer durch vier teilbaren Addresse beginnt. Was du dagegen tun kannst? Structure packing auf 1 runterstellen. Dann bricht dir aber die Performance gerade deswegen zusammen.
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Würden mehr Leute ihre Programme optimieren, müsste man sich nicht alle paar Jahre neue Hardware anschaffen aber natürlich würde die Industrie nichts daran verdienen, immerhin will sie ja, dass wir uns neue kaufen.
KKrieger verschwendet haufenweise RAM. Nur mal so nebenbei. Und so schön prozedurale Erstellung von Texturen und Sounds auch ist (nur so wurde es so klein), so lässt sich auf Dauer nicht produktiv Software oder gar Spiele entwickeln, die den Qualitätsansprüchen genügt. Generierte Texturen und Sounds werden nie das sein, was Grafiker oder Tonstudios produzieren können. Weder von der Geschwindigkeit der Herstellung, noch der Qualität.wenn ich das schon sehe wie groß manche Executables von Computerspielen sind, wird mir schlecht und dann wird auch meistens extrem viel RAM alloktiert, ganz einfach weil z.B. ein paar Leute zu Faul waren darauf zu achten ob sie Variablen benutzen die nur ein Byte groß sind oder ganze vier oder darauf zu achten ob man irgendwo noch Variablen einsparen kann, ohne, dass dies auf Kosten der Rechenzeit geschieht. Irgendwann rechnet sich das natürlich, bei sehr großen Arrays oder einer riesigen Menge von Variablen. Sieh dir mal Programme wie kkrieger an, die arbeiten wirklich effektiv zumindest was Festplattenspeicher angeht
Ja. Weil die Adresse nicht durch 4 teilbar ist, wird das Laden der Daten schonmal langsamer, z.B. Caching spielt hier rein. Wenn Du dann noch anfängst und aus jedem Laden einer Variable nicht 2 Takte, sondern 8 zu machen... ja nee, is sicher schneller. Pipelining kannste hier dann auch komplett in die Tonne treten, Du musst die Daten ja seriell aufbereiten. Das kann gar nicht schneller sein als mit Alignment. Nie im Leben.Dann ist das aber nicht mein Fehler sondern der des Compilers, immerhin könnte man unter einer Adresse die durch vier teilbar ist auch zwei oder mehr Variablen die kleiner sind als Long unterbringen. Oder willst du mir erzählen, dass die paar Modulooperationen und Bitshifts die nötig wären um die Variablen wieder einzellnd in ein Register zu kriegen, die Rechenleistung dermaßen abbremsen?
Compiler sind oft sehr ineffizient, wie ich bereits geschrieben habe, 1/3 Maschinencode Instruktionen zuviel ist schon was, das kannst du gleichsetzen mit: "Es ist mehr als 1/3 der Rechenleistung einsparbar.". Es gibt außerdem noch die High und Low Register sowie ein 16-bit Register und soweit ich weiß hat sich an der Architektur seit DOS Zeiten nicht sehr viel getan und da waren, auch noch gegen Ende der DOS Ära die Programme auf optimale Speichernutzung ausgelegt.
Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von »BlueCobold« (28.06.2012, 12:56)
Und was Jonathan meinte: Eine Struct aus zwei Shorts muss nicht unbedingt weniger Platz benutzen als eine Struct aus einem Long und einem Short. CPUs kommen schlecht mit Addressen zurecht die nicht durch vier teilbar sind, deswegen wird der Compiler selbstständig einen kleinen Pufferbereich einschieben, damit der zweite Short auch bei einer durch vier teilbaren Addresse beginnt. Was du dagegen tun kannst? Structure packing auf 1 runterstellen. Dann bricht dir aber die Performance gerade deswegen zusammen.
Dann ist das aber nicht mein Fehler sondern der des Compilers, immerhin könnte man unter einer Adresse die durch vier teilbar ist auch zwei oder mehr Variablen die kleiner sind als Long unterbringen. Oder willst du mir erzählen, dass die paar Modulooperationen und Bitshifts die nötig wären um die Variablen wieder einzellnd in ein Register zu kriegen, die Rechenleistung dermaßen abbremsen? Compiler sind oft sehr ineffizient, wie ich bereits geschrieben habe, 1/3 Maschinencode Instruktionen zuviel ist schon was, das kannst du gleichsetzen mit: "Es ist mehr als 1/3 der Rechenleistung einsparbar.". Es gibt außerdem noch die High und Low Register sowie ein 16-bit Register und soweit ich weiß hat sich an der Architektur seit DOS Zeiten nicht sehr viel getan und da waren, auch noch gegen Ende der DOS Ära die Programme auf optimale Speichernutzung ausgelegt.
Werbeanzeige