Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 20 von 35

Thema: Ich HASSE *insert Sprache here*, aber ich LIEBE *insert another Sprache here*

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Das ist mir jetzt irgendwie peinlich, aber genau einen Tag nach meinem Post muss ich meine Aussage bezüglich C# schon revidieren. Just gestern Abend ist C# nämlich extrem in meiner Gunst gefallen. Es stimmt zwar immer noch alles, was ich da oben gesagt habe, allerdings hat C# ein großes Problem: Den Garbage Collector. Das mag jetzt widersprüchlich klingen, denn erst gestern habe ich gerade den noch implizit gelobt. Eigentlich ist die Idee des Garbage Collectors auch eine recht clevere Sache. Das Problem ist nur, dass der Garbage Collector das absolute Todesurteil für jede komplexere Anwendung ist, die viel Speicher verwendet. Zum Beispiel ein Spiel. Und natürlich fällt mir das erst gestern Abend, als sich unser Semesterprojekt schon langsam dem Alpha-Status nähert, zum allerersten mal auf. Toll! Jetzt haben wir hier ein fast feature-komplettes Spiel in das sehr viel Zeit und Mühe investiert wurde, aber wenn zu viele Bullets verschießt, fängt das Spiel plötzlich bis zur Unspielbarkeit an zu laggen und es gibt so rein gar nichts, was wir dagegen unternehmen können. Ich habe schon alle Möglichkeiten des Garbage Collectors durchprobiert. Unser erstes Level ist nur dann bis zum Ende durchspielbar (und mit Ende meine ich nur das aktuelle Ende, ca. drei Minuten Spielzeit, es war noch mehr geplant), wenn man darin echt sparsam mit seinen Waffen umgeht und möglichst nur schießt, wenn auch Gegner in der Schusslinie sind. Damit ist mein Urteil gefallen: So sehr ich C# als Sprache auch mag, für Spiele werde ich es definitiv nie wieder einsetzen.

  2. #2
    Zitat Zitat von RPG Hacker Beitrag anzeigen
    So sehr ich C# als Sprache auch mag, für Spiele werde ich es definitiv nie wieder einsetzen.
    Unity

  3. #3
    Und gefühlte zwei Minuten später muss ich auch die Aussage wieder revidieren. Es war gar nicht der Garbage Collector, der den Slowdown verursacht hat, sondern ich hatte nur aus Versehen vergessen, nach rechts fliegende Projektile zu despawnen, nachdem sie den Bildschirm verlassen. Das hat meine Kollisionsabfrage gesprengt.

    Peinlich! ^^"
    Jetzt komme ich mir echt, wie so ein n00b vor! Und C# bin ich jetzt wohl eine Entschuldigung schuldig. Tut mir Leid, C#! Du bist immer noch meine Lieblings-Programmiersprache!

  4. #4
    @RPG Hacker:
    Als ich deinen Meckerpost gelesen hab war ich schon voll drauf eingestimmt dir die Ohren langzuziehen ;-)

    Der Trick mit dem GarbageCollector in Anwendungen in denen man sich GC-Lags nicht erlauben kann ist einfach: den GC erzwingen.
    Ich mache das in meinen Industrieprogrammen hier alle 40 Millisekunden. Ein GC-Aufruf dauert dann eine halbe Millisekunde ( die Software dient dem Zweck Daten aufzunehmen, zu verarbeiten und wegzuschmeissen, es passiert also auch was ).

    Irgendwo solltest du eine Art Gameloop haben, pack den GC.Collect(); ans Ende.

    Btw. Wenn du JIT-Kompilierung "vorwegnehmen" willst:
    http://www.codeproject.com/Articles/...-the-fly-or-tr
    Kann auch hilfreich sein wenn man sein Timing besser im Griff haben möchte.

  5. #5
    Zitat Zitat von Corti Beitrag anzeigen
    Der Trick mit dem GarbageCollector in Anwendungen in denen man sich GC-Lags nicht erlauben kann ist einfach: den GC erzwingen.
    Ich mache das in meinen Industrieprogrammen hier alle 40 Millisekunden. Ein GC-Aufruf dauert dann eine halbe Millisekunde ( die Software dient dem Zweck Daten aufzunehmen, zu verarbeiten und wegzuschmeissen, es passiert also auch was ).
    Ich kann mir allerdings vorstellen, dass es spätestens bei 60 FPS trotzdem auffällt und die Anwendung verlangsamt oder Input-Lag erzeugt. Besonders, wenn man auch noch Physik-Berechnungen oder so drin hat.

    Zitat Zitat von Corti Beitrag anzeigen
    Irgendwo solltest du eine Art Gameloop haben, pack den GC.Collect(); ans Ende.
    Bringt das denn auch was? Irgendwo im Internet habe ich gelesen, dass GC.Collect() keine wirkliche Garbage Collection garantiert, sondern nur, dass der Garbage Collector bestimmte organisationstechnische Tasks erledigt, die mit Gabage Collection im Zusammenhang stehen.

    Mittlerweile wird GC.Collect() bei mir aber aufgerufen, sobald das Level beendet wird. Vorausgesetzt das Level funktioniert auch weiterhin ohne Slowdowns, dann sollte das auf jeden Fall ausreichen, da eventuelle, bemerkbare Slowdowns dann eh während eines Blackscreens auftreten würden und das nächste Level dann wieder genug RAM zur Verfügung hätte.

    Zitat Zitat von Corti Beitrag anzeigen
    Btw. Wenn du JIT-Kompilierung "vorwegnehmen" willst
    Interessant. Ich nehme an das bringt mir eine geringe Performance-Verbesserung?

  6. #6
    Zitat Zitat von RPG Hacker Beitrag anzeigen
    Ich kann mir allerdings vorstellen, dass es spätestens bei 60 FPS trotzdem auffällt und die Anwendung verlangsamt oder Input-Lag erzeugt. Besonders, wenn man auch noch Physik-Berechnungen oder so drin hat.
    Naja, wir leben ja nicht mehr in Zeiten, wo alles nur sequenziell abgearbeitet wird. Es laufen dort ja nebenbei Threads, die sich die Arbeit aufteilen. Ab C# 5.0 gibt es ja auch noch parallele Verarbeitungen. Dabei muss der Entwickler sich nicht mehr um jeden Thread selbst kümmern, sondern er regelt primär die Aufgabenverteilung. Die Erstellung der Threads geschieht dann zur Laufzeit automatisch. Hierbei wird dann auch automatisch entschieden, wie viele Threads gestartet werden sollen. Befindet sich ein Dualcore-CPU im Einsatz, werden zwei Threads gestartet. Bei einem Quadcore-CPU vier Threads, etc. Das kann erhebliche Vorteile bringen, aber auch Nachteile, wenn die ausführenden Aktionen nicht komplex genug sind und mehr Zeit beim Erstellen und Löschen der Threads verbraten wird.

    GC.Collect() sollte man aber auch nur aufrufen, wenn man gute Gründe dafür hat. Es bringt nicht viel, ihn jedes Mal anzuschmeißen, da auch das wegschmeißen von Objekten nicht kostenlos ist, auch wenn viele das Gegenteil behaupten. Soll heißen: Der Prozessor braucht auch hier eine gewisse Rechenzeit. Wenn man den GC zu oft aufruft, kann es schon deutlich die Performance mindern. Es macht keinen Sinn, den GC anzuschmeißen, wenn nur eine Hand voll Objekte gelöscht werden sollen. Daher sollte man schon Performace-Tests durchführen, ob es wirklich was bringt.

    In der Firma, wo ich arbeite, hantieren wir mit Millionen von Objekten rum (eine Software für Banken), und wir rufen lediglich nur ein einziges Mal den GC auf, wenn die Anwendung mit einer vorerst nicht wiederkehrenden Berechnung fertig ist. In diesem Zusammenhang empfehle ich mal eine Stack Overflow Foren-Diskussion: http://stackoverflow.com/questions/4...all-gc-collect

  7. #7
    Zitat Zitat
    Ich nehme an das bringt mir eine geringe Performance-Verbesserung?
    Njein. JIT passiert sonst beim ersten Aufruf. Der erste Aufruf sollte also geringfügist schneller gehen. Erwarte keine Wunder und nix was du siehst und fühlst wenn du nicht grade Millisekunden mit Nachkommastelle misst.


    Zitat Zitat
    Ich kann mir allerdings vorstellen, dass es spätestens bei 60 FPS trotzdem auffällt und die Anwendung verlangsamt oder Input-Lag erzeugt. Besonders, wenn man auch noch Physik-Berechnungen oder so drin hat.
    Was Programmierst du? Crysis3 in einem Single-Threaded Gameloop? Bei anspruchsvollen Anwendungen muss man sich sowieso überlegen, wie man die gesamte Leistung des Rechners abruft, nicht alle Operationen müssen in jedem Takt einmal gemacht werden etc. die Halbe/Millisekunde ist kein Performancekiller. GarbageCollection als großer böser, fieser Performancekiller ist ein Mythos damit Menschen ohne technischen Sachverstand besser "C++ VS C#/Java" diskutieren können ;-)

    @Whiz-zarD:
    Zitat Zitat
    GC.Collect() sollte man aber auch nur aufrufen, wenn man gute Gründe dafür hat.
    Ich hab bisher keine Anwendung entwickelt, bei der "falsche" GC-Aufrufe irgendeine Konsequenz gehabt hätten. Ich kann mir aber vorstellen, dass man deine Bankensoftware lieber machen lassen sollte. Benutzt ihr da eigentlich schon .NET 4.5 und diese Features für paralleleles GC-Collecten? Wie häufig kommt bei euch denn automatisches GC vor?

    Die Zeit zum Wegschmeissen von Objekten ist nicht das Problem bei zyklischen GC Aufrufen. Wenn man keine großen Lags durch GC haben möchte lohnt es sich öfter mal kleine Mengen Daten zu entsorgen statt einmal eine große Menge. Problematischer ist eher, dass GC auch wenn nichts zu sammeln ist eine gewisse Zeit braucht um zu prüfen ob was wegwerfwürdig ist, diese Zeit bewegt sich aber im Bereich halbe Millisekunden bis Millisekunde, also durchaus etwas, dass man in einem Gameloop mal unterbringen kann ohne, dass die Performance so kaputt geht, dass man sich denkt "Gott hätte ich lieber C++ genommen".

  8. #8
    Zitat Zitat von Corti Beitrag anzeigen
    Benutzt ihr da eigentlich schon .NET 4.5 und diese Features für paralleleles GC-Collecten? Wie häufig kommt bei euch denn automatisches GC vor?
    Leider nein. Wir dümpeln noch bei .NET 2.0 rum, weil wir auf die Kunden achten müssen und viele Kunden reagieren bei Updates mit Panik.
    Das ist echt schlimm. Das hat zur Folge, dass wir ungefähr 15 Release-Zweige pflegen müssen, weil Kunden Angst haben z.B. von einer Version 3.19 auf eine 3.20 zu wechseln, also müssen wir dann dort eine 3.19.100 eröffnen.
    Naja, das sind halt Banken. Bei denen gilt: "Don't touch a running system!". Da kann es schon mal vorkommen, dass eine Software über 30 Jahre ihren Dienst verrichten, ehe sie gegen eine neue Ausgetauscht wird.

    Den GC rufen wir nur noch ein mal auf, wenn er eine komplexe Berechnung erledigt hat. Solche Berechnungen können mehrere Stunden dauern und Millionen von Geschäftsobjekten erzeugen.

  9. #9
    Hrm~ ^^"" Mein Beileid. Stell ich mir sehr ärgerlich vor, ich möchte die schönen neuen Asynchron- und Parallelfunktionen etc. nicht missen wollen.

    Ich kann aber leider auch nicht weiter als 4.0 weil die Maschinenrechner alle XP haben und 4.5 gibts dafür nicht.

    Geändert von Corti (08.01.2013 um 10:48 Uhr)

  10. #10
    Ich habe völlig vergessen zu erwähnen, dass ich mit Turbo Pascal 5 (oder war es schon Turbo Pascal 6? naja das war 100% noch DOS mit dem schönen Runtime error 200) das erste mal mit einer Programmiersprache in der der Schule in Kontakt gekommen bin, das war aber erst 2007, wo Turbo Pascal eigentlich schon klinisch tot war.

    Allerdings habe ich Pascal nie so gemocht. Das man die Funktionen/Prozeduren nicht einfach irgendwo im Quelltext packen konnte sondern er nur in Reihenfolge, hat mich angekotzt.

    Ob man nun den Klammer-Affen wie bei C, Java usw. spielen muss oder nun "begin", "end" usw. als benannte Klammern hat, das ist mir recht egal.
    Zur Not kann ich in C z.B. den Präprozessor nehmen und einfach oben "begin", "end" usw. als "{" und "}" deklarieren. Jeder C-Programmierer würde mich dafür erschießen, aber es ist möglich ohne das Kompilat zu verändern.

    Zitat Zitat von Whiz-zarD Beitrag anzeigen
    Leider nein. Wir dümpeln noch bei .NET 2.0 rum, weil wir auf die Kunden achten müssen und viele Kunden reagieren bei Updates mit Panik.
    Das ist echt schlimm. Das hat zur Folge, dass wir ungefähr 15 Release-Zweige pflegen müssen, weil Kunden Angst haben z.B. von einer Version 3.19 auf eine 3.20 zu wechseln, also müssen wir dann dort eine 3.19.100 eröffnen.
    Naja, das sind halt Banken. Bei denen gilt: "Don't touch a running system!". Da kann es schon mal vorkommen, dass eine Software über 30 Jahre ihren Dienst verrichten, ehe sie gegen eine neue Ausgetauscht wird.
    Bei denen läuft bestimmt noch Windows 2000. Das baut doch echt Vertrauen auf, da es ja selbst für Windows 2000 keinen Extended Support mehr gibt.
    Da funktionieren wahrscheinlich die ganzen Exploits der letztem 3 Jahre noch, auch wenn das ein super-abgeschottetes-System-mit-Internet-Anschluss ist.
    Zumindest arbeiten ja deine Kunden anscheinend nicht mehr mit einem uralten Unix, dass ja das Jahr-2038-Problem bestimmt noch hatte.
    Wenn auch schon ein kleiner Versionssprung von 3.19 auf eine 3.20 Panik aufruft, dann will ich nicht wissen, wie die z.B. auf die Versionssprünge bei Google Chrome oder (seit einiger Zeit auch) bei Firefox reagieren.

    Ca. 15 Release-Zweige der selben Software zu pflegen sind schon echt viele. Da gestaltet sich die Bug-Jagd und Pflege nicht gerade einfach. Denn bei so vielen Release-Zweigen verliert man irgendwann den Überblick.
    Ich höre oft, dass Software meist einen Lebenszyklus von ein paar Jahren hat, aber 30 Jahre alte Software - die wurde wahrscheinlich noch auf 5 1/4"-Disketten geliefert. Unvorstellbar dass so etwas noch mit Geld arbeitet.
    Das kostet ein Haufen Geld eine veraltete Software zu warten und das bei den ganzen "Notleidenden Banken" in der Krise.

  11. #11
    Zitat Zitat von niR-kun Beitrag anzeigen
    Bei denen läuft bestimmt noch Windows 2000. Das baut doch echt Vertrauen auf, da es ja selbst für Windows 2000 keinen Extended Support mehr gibt.
    Da funktionieren wahrscheinlich die ganzen Exploits der letztem 3 Jahre noch, auch wenn das ein super-abgeschottetes-System-mit-Internet-Anschluss ist.
    Zumindest arbeiten ja deine Kunden anscheinend nicht mehr mit einem uralten Unix, dass ja das Jahr-2038-Problem bestimmt noch hatte.
    Wenn auch schon ein kleiner Versionssprung von 3.19 auf eine 3.20 Panik aufruft, dann will ich nicht wissen, wie die z.B. auf die Versionssprünge bei Google Chrome oder (seit einiger Zeit auch) bei Firefox reagieren.
    Der Absatz ließt sich etwas arrogant finde ich. Du denkst zu sehr aus deiner "Informatiker"-Sicht. Versuch mal das aus den Augen eines großen Bankunternehmns zu sehen. Die arbeiten mit Geld, sie arbeiten mit DEINEM Geld. Für die sind Computer nur mittel zum Zweck (ein Mittel das durchaus Fehler verursachen kann) und wenn dann ein System gut läuft und alles gut macht, dann würde ich mich auch über neuere Versionen fürchten. Gerade als Programmierer sollte man wissen wie schnell sich Fehler einschleichen die man nicht erkennt weil man Software nicht so benutzt wie das der Verbraucher benutzen würde.

    Beschäftige dich mal mit den Computersystemen von Banken. Die haben fast alle Uralt-Software. Warum? Weil es funktioniert. Das ist für die wichtiger als fancy graphics oder feature-creep. Was meinst du wieviel Geld mit Softwareintegration gemacht wird (Also mit dem Entwicklen von Schnitstellen für Altsysteme).

  12. #12
    Zitat Zitat von Corti Beitrag anzeigen
    Was Programmierst du? Crysis3 in einem Single-Threaded Gameloop?
    Nein, das nun nicht gerade. War ja auch nur so eine Idee. Ich weiß ja nicht, wie GC.Collect() arbeitet und wie viel Performance er benötigt. Und auch habe ich noch keine Erfahrung darin, wie viel Performance so ein 2D Sidescroll Shooter (ala Contra oder Metal Slug) schluckt. Ist ja immerhin erst unser erstes Projekt. Ich sagte ja auch nur, dass ich es mir vorstellen kann.

  13. #13
    Zitat Zitat von R.D. Beitrag anzeigen
    (Also mit dem Entwicklen von Schnitstellen für Altsysteme).
    Generell das Entwickeln von Schnittstellen. Bei Banken kommt ja nicht nur eine Software zum Tragen, sondern gleich mehrere, die untereinander funktionieren müssen. D.h. es müssen Schnittstellen gebaut werden.
    Unsere Software bekommt die Daten von anderer Software eines anderen Hersteller. Dafür haben wir dann Schnittstellen gebaut. Wenn sich dann was an einer Software ändert und unsere Schnittstelle kann damit nicht umgehen, dann ist es meist schon zu spät. Wenn Updates eingespielt werden müssen, dann wird das eh erst Monatelang in einem Testsystem beobachtet, ob sich alles verhält, wie es soll, ehe das Update wirklich live geht.

    Zitat Zitat von RPG Hacker Beitrag anzeigen
    Nein, das nun nicht gerade. War ja auch nur so eine Idee. Ich weiß ja nicht, wie GC.Collect() arbeitet und wie viel Performance er benötigt. Und auch habe ich noch keine Erfahrung darin, wie viel Performance so ein 2D Sidescroll Shooter (ala Contra oder Metal Slug) schluckt. Ist ja immerhin erst unser erstes Projekt. Ich sagte ja auch nur, dass ich es mir vorstellen kann.
    Generell würde ich da sagen, dass ihr euch da erstmal keine Gedanken machen braucht. Das anschmeißen des GCs sind eher minimale Optimierungen, die man erst mal vernachlässigen sollte.
    Falls ihr irgendwo Performanceprobleme haben solltet, dann liegen sie meist an einer anderen stelle. Gerade was Grafiken angeht, tappt man gerne als Anfänger in diverse Fallen. Ich kann davon ein Liedchen singen, als ich in meiner Ausbildung ein MS Paint-Klon basteln sollte. So trivial ist die ganze Thematik nämlich nicht. Ich weiß zwar nicht, mit was ihr euer Spiel entwickelt, aber ich würde euch raten, mal XNA anzuschauen, falls ihr das nicht schon tut. Das Framework ist sehr mächtig und auch recht gut dokumentiert.

    Und außerdem: Du arbeitet sehr wohl mit Pointern in C#. Nur nennen sich diese hier Referenzen.
    Wenn du ein Objekt instanzierst, bekommst du als Rückgabewert ein Pointer auf dein Objekt.

  14. #14
    Zitat Zitat von Whiz-zarD Beitrag anzeigen
    Ich weiß zwar nicht, mit was ihr euer Spiel entwickelt, aber ich würde euch raten, mal XNA anzuschauen, falls ihr das nicht schon tut. Das Framework ist sehr mächtig und auch recht gut dokumentiert.
    Jab, wir benutzen XNA. Aber ehrlich gesagt bin ich davon nicht nur begeistert. XNA bietet zwar ein nettes Framework, mit dem man schnell in eine Engine einsteigen kann und die wichtigsten Funktionen gleich schon geboten bekommt (was auch durch die Einfachheit von C# noch unterstützt wird), oftmals ist aber gerade dieses hohe Level genau das Problem. Bestimmte Tweaks am zu Grunde liegenden System sind erst gar nicht möglich ohne eine komplett eigene Engine zu schreiben. Die Erfahrung habe ich jedenfalls gemacht, wenn es beispielsweise um so Sachen geht wie Timing. Konkret habe ich mal versucht, Interpolation in ein Spiel einzubauen. Und obwohl auf MSDN steht, dass in XNA die Draw-Methode selbst dann noch möglichst oft aufgerufen wird, wenn man das Spiel auf Fixed Time Steps stellt, hat das bei mir nicht so wirklich funktioniert. Faktisch wurden Update und Draw bei mir immer noch gleich oft aufgerufen. Beispielsweise hatte ich mal testweise die Update-Frequenz auf 4 FPS gesetzt. Der Effekt war, dass auch Draw nur mit 4 FPS aufgerufen wurde. Solches Verhalten zu verändern wird in XNA beispielsweise nicht leicht.

    Eine andere Sache, die mir in XNA nicht gefällt, ist dass es viele Sachen komplizierter macht als nötig. Zur Erläuterung: In unserem Spiel gibt es einen Laser, der Ray-Tracing verwendet und genau bis zur nächsten Wand fliegt. Zur Darstellung verwenden wir Tiles, die wir x-mal wiederholen. Nun dachten wir uns, dass es vielleicht einen ganz guten Effekt gäbe, wenn wir den Laser per Add-Blending darstellen. War auch an und für sich keine schlechte Idee, nur haben die Tiles sich an den Übergängen überlappt (was in XNA sonst kaum anders lösbar wäre aufgrund gewisesr Eigenschaften), was bei Add-Blend natürlich bedeutet, dass an dieser Stelle doppelt addiert wird und man Übergangskanten hat. Schön und gut dachte ich mir. Zeichne ich den Laser einfach vorher per Alpha-Blend auf einen Buffer und dann von da per Add-Blend auf den Bildschirm. Aber nein, Pustekuchen. Das einzige, was ich dafür hätte verwenden können, sind RenderTargets. Und die sind einfach so ziemlich das schlimmste, was es in XNA gibt. Jeder, der damit schonmal gearbeitet hat, kennt sicher das Problem mit der lilanen Farbe im Hintergrund. Ich schwöre: Ich habe ein paar Stunden lang gegoogelt und diverse als funktionierend abgestempelte Methoden teilweise eins zu eins übernommen. Ich habe es einfach nicht geschafft, die Farbe rauszukriegen. In anderen Libraries, beispielsweise Allegro, hätte ich an diesem Problem vielleicht fünf Minuten gesessen.

    Also wie gesagt: XNA ist schon ein nettes Framework für den Einstieg in eine eigene Engine, weil es einem viel Arbeit schon abnimmt, aber für ein wirklich ernsthaftes Projekt, für das ich etwas mehr Zeit hätte, würde ich es nicht verwenden wollen.

    Zitat Zitat von Whiz-zarD Beitrag anzeigen
    Und außerdem: Du arbeitet sehr wohl mit Pointern in C#. Nur nennen sich diese hier Referenzen.
    Wenn du ein Objekt instanzierst, bekommst du als Rückgabewert ein Pointer auf dein Objekt.
    Klar. Habe ich denn was anderes behauptet? Ich bin ja nicht auf den Kopf gefallen. Natürlich sind Referenzen in C# nichts anderes als Pointer. Fakt ist aber, dass du sie nicht als Pointer verwendest. Das macht C# eben schon automatisch für dich. Für dich als Programmierer hingegen gibt es in C# in der Nutzung erstmal keinen Unterschied zwischen Reference-Typen und Value-Typen, die werden alle wie letzterer verwendet. Was ich damit sagen will: Wenn du beispielsweise eine Funktion mit Parametern schreibst, macht es für dich keinen Unterschied, ob du einen int übergibst oder eine Klasse. C# wählt automatisch die bestmögliche Option für dich. In C++ hingegen müsstest du selbst entscheiden, ob du die Klasse lieber als Daten oder als Referenz übergibst.

    Auch das alles hat natürlich nicht nur gute Seiten. Ein Problem hiervon ist zum Beispiel, dass du an die Vorgaben von C# gebunden bist. So kannst du beispielsweise einen int niemals als Referenztyp und eine Klasse niemals als Valuetyp übergeben. Das ist zwar nur in den seltensten Fällen überhaupt nötig, aber durchaus nicht komplett ausgeschlossen. Zumindest der erste Fall. Um das in C# hinzukriegen musst du schon einen Umweg gehen und den Valuetyp irgendwie extra in eine Klasse packen. Und das ist eben genau das, was ich meine. Wirklich mit Pointern arbeiten tust du in C# eigentlich nur in Unmanaged Code. Ansonsten tut C# das automatisch und es kann dir egal sein, ob da gerade Pointer verwendet werden oder nicht. Eben auch wegen der automatischen Speicherverwaltung und so.

  15. #15
    Zitat Zitat von Whiz-zarD Beitrag anzeigen
    Generell das Entwickeln von Schnittstellen. Bei Banken kommt ja nicht nur eine Software zum Tragen, sondern gleich mehrere, die untereinander funktionieren müssen. D.h. es müssen Schnittstellen gebaut werden.
    Unsere Software bekommt die Daten von anderer Software eines anderen Hersteller. Dafür haben wir dann Schnittstellen gebaut. Wenn sich dann was an einer Software ändert und unsere Schnittstelle kann damit nicht umgehen, dann ist es meist schon zu spät. Wenn Updates eingespielt werden müssen, dann wird das eh erst Monatelang in einem Testsystem beobachtet, ob sich alles verhält, wie es soll, ehe das Update wirklich live geht.
    Deswegen "Altsysteme". Ich tue mir das in der Uni auch grad an und kann daher gut mit dir mitfühlen auch wenn es bei uns nicht so schlimm ist.

    Zitat Zitat von RPG Hacker Beitrag anzeigen
    Jab, wir benutzen XNA. Aber ehrlich gesagt bin ich davon nicht nur begeistert. XNA bietet zwar ein nettes Framework, mit dem man schnell in eine Engine einsteigen kann und die wichtigsten Funktionen gleich schon geboten bekommt (was auch durch die Einfachheit von C# noch unterstützt wird), oftmals ist aber gerade dieses hohe Level genau das Problem.
    Das fasst meine Meinung über XNA gut zusammen. Es stellt sich zwar mächtig hin, versagt aber bei den kleinen Sachen (Versuch mal ordentlich Primitves zu zeichnen...). Ich weiß jetzt nicht wie MonoGame ist und kenne auch nur ein Game damit (Bastion), aber das ist Open Source und daher würde ich nie das tote XNA empfehlen.

    Zitat Zitat
    Eine andere Sache, die mir in XNA nicht gefällt, ist dass es viele Sachen komplizierter macht als nötig. Zur Erläuterung: In unserem Spiel gibt es einen Laser, der Ray-Tracing verwendet und genau bis zur nächsten Wand fliegt. Zur Darstellung verwenden wir Tiles, die wir x-mal wiederholen. Nun dachten wir uns, dass es vielleicht einen ganz guten Effekt gäbe, wenn wir den Laser per Add-Blending darstellen. War auch an und für sich keine schlechte Idee, nur haben die Tiles sich an den Übergängen überlappt (was in XNA sonst kaum anders lösbar wäre aufgrund gewisesr Eigenschaften), was bei Add-Blend natürlich bedeutet, dass an dieser Stelle doppelt addiert wird und man Übergangskanten hat. Schön und gut dachte ich mir. Zeichne ich den Laser einfach vorher per Alpha-Blend auf einen Buffer und dann von da per Add-Blend auf den Bildschirm. Aber nein, Pustekuchen. Das einzige, was ich dafür hätte verwenden können, sind RenderTargets. Und die sind einfach so ziemlich das schlimmste, was es in XNA gibt. Jeder, der damit schonmal gearbeitet hat, kennt sicher das Problem mit der lilanen Farbe im Hintergrund. Ich schwöre: Ich habe ein paar Stunden lang gegoogelt und diverse als funktionierend abgestempelte Methoden teilweise eins zu eins übernommen. Ich habe es einfach nicht geschafft, die Farbe rauszukriegen. In anderen Libraries, beispielsweise Allegro, hätte ich an diesem Problem vielleicht fünf Minuten gesessen.
    In XNA kannst du eine Textur nicht stretchen? Das glaub ich irgendwie nicht Also wenn der Laser eine komplizierte horizontale Animation hat sondern einfach nur ein Streifen, hätte es auch ein Strech getan denke ich. Ich dachte immer RenderTargets sind einfach nur FrameBuffer. Das man da soviel kaputt machen kann wusste ich nicht (also, das die engine Entwickler offenbar da Probleme hatten.).

    Zitat Zitat
    Also wie gesagt: XNA ist schon ein nettes Framework für den Einstieg in eine eigene Engine, weil es einem viel Arbeit schon abnimmt, aber für ein wirklich ernsthaftes Projekt, für das ich etwas mehr Zeit hätte, würde ich es nicht verwenden wollen.
    Naja für simple pixelbasirende Spiele wird es gehen. Auch für simples 3D. Siehe Terraria oder Secret of Grindea.


    Zitat Zitat
    Klar. Habe ich denn was anderes behauptet? Ich bin ja nicht auf den Kopf gefallen. Natürlich sind Referenzen in C# nichts anderes als Pointer.
    Ich meine Pointer zeigen auf nichts oder? Aber eine Referenz zeigt doch auf etwas selbst wenn man nichts darauf verweißt. Zumindest ist das in Java so.

  16. #16
    Zitat Zitat von RPG Hacker Beitrag anzeigen
    Fakt ist aber, dass du sie nicht als Pointer verwendest. Das macht C# eben schon automatisch für dich. Für dich als Programmierer hingegen gibt es in C# in der Nutzung erstmal keinen Unterschied zwischen Reference-Typen und Value-Typen, die werden alle wie letzterer verwendet. Was ich damit sagen will: Wenn du beispielsweise eine Funktion mit Parametern schreibst, macht es für dich keinen Unterschied, ob du einen int übergibst oder eine Klasse. C# wählt automatisch die bestmögliche Option für dich. In C++ hingegen müsstest du selbst entscheiden, ob du die Klasse lieber als Daten oder als Referenz übergibst.
    Doch, es gibt einen gravierenden Unterschied. Wertetypen werden im Stack alloziert und wird durch einen sog. Stack Pointer direkt vom Prozessor unterstützt.
    Referenztypen hingegen werden im Heap alloziert. Das allozieren muss man explizit mit dem new-Schlüsselwort einleiten, ansonsten hat man hier einen Null-Pointer. Wertetypen hingegen können nicht null als Wert besitzen. Wer sowas braucht, der muss Wrapper-Klassen benutzen. Unter C# wäre dies z.B. int?. Das Fragezeichen deutet darauf hin, dass sich um eine Wrapper-Klasse von einem Wertetyp handelt.

    Ein weiterer Unterschied ist der Pointer selbst:
    Code:
    int a = 5;
    int b = a;
    Hier haben wir zwei unabhängige Wertetypen, die jeweils den Wert 5 besitzen.
    Code:
    Circle cirlce1 = new Cirlce();
    Circle circle2 = circle1;
    Hier zeigen beide Referenztypen auf das selbe Objekt, und es ist auch egal, ob ich circle1 oder circle2 nehme.
    Beide Code-Abschnitte machen im Prinzip das selbe, wir deklarieren zwei Variablen, eine Initialisieren wir und der zweiten übergeben wir dem Wert der ersten Variable, aber wir haben hier zwei unterschiedliche Ergebnisse.
    Im ersten Beispiel übergeben wir den Wert und im zweiten Beispiel die Referenz.
    Soll heißen: Nur weil man nicht explizit mit Pointern arbeitet, heißt es ja lange nicht, dass es keine Pointer mehr gibt, und der letzte zitierte Satz:

    Zitat Zitat
    In C++ hingegen müsstest du selbst entscheiden, ob du die Klasse lieber als Daten oder als Referenz übergibst.
    Zeigt, dass du die Pointer nicht so ganz verstanden hast, denn das tust du unter C# auch. Nur ist die Syntax in C# nicht ganz so kryptisch, wie bei C/C++.
    Auch bei C# musst du entscheiden, ob du einen Werteparameter (Call-by-Value), oder einen Referenzparameter (Call-by-Reference) an eine Methode übergeben möchtest.

  17. #17
    Zitat Zitat von R.D. Beitrag anzeigen
    In XNA kannst du eine Textur nicht stretchen? Das glaub ich irgendwie nicht Also wenn der Laser eine komplizierte horizontale Animation hat sondern einfach nur ein Streifen, hätte es auch ein Strech getan denke ich. Ich dachte immer RenderTargets sind einfach nur FrameBuffer.
    Natürlich geht das. Weiß nur nicht, ob das auch noch so gut funktioniert, wenn du den Laser rotierst (du gibst bei der Skalierung X- und Y-Skalierung an). Vor allen Dingen aber wollten wir eben keinen langweiligen Laser, der einfach nur aus einem Strahl besteht. Wir wollten schon ein bisschen mehr Struktur reinbringen.

    Zitat Zitat von Whiz-zarD Beitrag anzeigen
    Soll heißen: Nur weil man nicht explizit mit Pointern arbeitet, heißt es ja lange nicht, dass es keine Pointer mehr gibt,
    Was ich nie auch nur ansatzweise behauptet habe.

    Zitat Zitat von Whiz-zarD Beitrag anzeigen
    und der letzte zitierte Satz Zeigt, dass du die Pointer nicht so ganz verstanden hast
    Sei mal nicht so arrogant. Das unterstreicht nur die Vorurteile, die man ohnehin schon gegenüber Programmierern hat. Ich verstehe echt nicht, warum 95% der Programmierer so verdammt arrogant sein müssen. Bloß, weil ich mich anders ausdrücke, als du, heißt das noch lange nicht, dass ich etwas nicht verstehe. Ich programmiere nun immerhin auch schon seit gut fünf Jahren und das zwar bisher noch nicht für ein Unternehmen, aber immerhin schon in den verschiedensten Programmiersprachen, darunter sogar ASM für das SNES. Und da es im guten alten Turbo Pascal noch nicht so Datentypen wie Listen oder Vektoren gab, habe ich selbst verständlich auch schon mit selbst programmierten, dynamisch verlinkten Listen gearbeitet. Zu behaupten, ich würde Pointer nicht verstehen, ist hier also pure Arroganz, bloß weil ich anderer Ansicht bin, als du (oder denselben Standpunkt anders darstelle). Komm mal von deinem hohen Ross runter, du göttlicher Super-Programmierer!

    Zitat Zitat von Corti Beitrag anzeigen
    Machts für dich keinen Unterschied mit einer Kopie oder dem Original zu arbeiten? Nie?
    Faktisch tatsächlich eher selten. Kann mich bisher eigentlich nur an einen Fall erinnern, wo ich mal die Kopie einer Klasse brauchte. Und da hätte ich theoretisch auch mit dem Original arbeiten können. Generell ist es eben einfach so, dass man Klassen meistens als Referenzen und andere Sachen meistens nur als Wert braucht. Das Standardverhalten ist in C# ja nicht grundlos so definiert. In 90% der Fälle ist das eben genau das, was man braucht.

    Zitat Zitat von Corti Beitrag anzeigen
    Ref: http://msdn.microsoft.com/de-de/libr...=VS.80%29.aspx
    Out: http://msdn.microsoft.com/de-de/libr...=vs.80%29.aspx

    Nicht die empfohlenste Art in C# mit Parametern zu hantieren aber ganz praktisch.
    Naja, ich habe da tatsächlich etwas ganz anderes gemeint, als ich gesagt habe. Was ich meinte war, dass du beispielsweise in einer Klasse nicht ohne Umwege eine Referenz auf einen Wertetyp deklarieren kannst. Also dass du beispielsweise in einer Klasse eine Eigenschaft namens intPointer hast, die auf einen int zeigt. Dafür müsstest du dann erst einen Wrapper oder so verwenden. In C++ (oder Unmanaged Code) könntest du ja einfach int* nehmen.

    Zitat Zitat von Corti Beitrag anzeigen
    Mach einen Clon O_o , es gibt Klassen, die akzeptieren ihre eigene Art im Konstruktor, wenn man es denn unbedingt einfach haben will, oder man schreibs sich selber kurz.
    Wenn das Ding eh nur Daten speichern soll mach 'n Struct draus.
    Ja, das ist auch nicht unbedingt das beste Beispiel. Der umgekehrte Fall, einen Wertetyp als Referenz zu verwenden, ist eh wahrscheinlicher.

    Zitat Zitat von Whiz-zarD Beitrag anzeigen
    C# sucht keine Option aus. C# erzeugt eine Kopie. Entweder eine Kopie des Wertetyps, oder eine Kopie der Referenz, je nachdem um was für ein Typ es sich handelt.
    Das ist doch überhaupt nicht der Punkt. Rede ich denn gegen eine Wand? Alles, was ich sage, ist dass der Unterschied zwischen Referenztypen und Wertetypen in C# einfach in 90% der Fälle für den Programmierer egal ist. Natürlich gibt es da Unterschiede, natürlich wird da mit Pointern gearbeitet, natürlich gibt es Ausnahmen. In 90% der Fälle - so war es zumindest bei mir bisher - arbeitet C# aber immer genau so, wie du es gerade erwartest bzw. brauchst. Das liegt eben auch daran, dass C# eben automatische Speicherverwaltung hat. Wenn du in C++ eine Funktion nimmst und ihr einen Pointer übergibst, musst du dir anschließend oft sagen "so, und jetzt nach der Funktion bloß nicht vergessen, den Speicher wieder freizugeben". In dieser Hinsicht unterscheiden sich in C++ Pointer stark von Wertetypen, denn Wertetypen musst du nie manuell freigeben. In C# hingegen musst du ja so gut wie nie Speicher manuell freigeben. Dadurch verschwimmen die Grenzen zwischen Referenztyp und Wertetyp in der Anwendung. Du musst dir nie erst sagen "Ach ja, das ist ja eine Referenz, also bloß nicht vergessen, den Speicher wieder freizugeben", sondern kann sie ähnlich, wie Wertetypen verwenden. Das ist doch wirklich alles, was ich damit habe sagen wollen. War das nun wirklich so schwer zu verstehen und diese ganze Diskussion wert? Mann, Mann, Mann...

  18. #18
    Zitat Zitat von RPG Hacker Beitrag anzeigen
    Sei mal nicht so arrogant. Das unterstreicht nur die Vorurteile, die man ohnehin schon gegenüber Programmierern hat. Ich verstehe echt nicht, warum 95% der Programmierer so verdammt arrogant sein müssen.
    Ich bin nicht arrogant. Anstatt die Fehler bei den anderen zu suchen, solltest du dich vielleicht mal fragen, warum du so empfindest, dass 95% der Programmierer arrogant seien.
    Es liegt einfach nur daran, dass du missverständliche Dinge von dir gibst, die ein Programmierer für falsch ansieht und dich lediglich korrigiert. Dein jetziger Beitrag ist auch wieder voller falschen Aussagen. Das fängt schon damit an, dass du den Gabage Collector und Pointer in einen Pott schmeißt. Auch in C/C++ kannst du ohne weiteres einen Garbage Collector implementieren.

  19. #19
    Genau das meine ich doch mit arrogant. Anstatt mich einfach nur sachlich auf die Fehler hinzuweisen (natürlich habe ich keine perfekte Ausdrucksweise und natürlich ist nicht alles, was ich sage, 100%ig korrekt - immerhin beginne ich gerade erst mit dem Studium und habe zuvor fast nur als Hobby programmiert) musst du mir natürlich noch unter die Nase reiben, WIE falsch ja alles sei, was ich sage, und wie viel besser du es wüsstest. Es ist schon ein deutlicher Unterschied, ob man sagt "Das ist so nicht ganz richtig. Tatsächlich gibt es da dieses und jenes.", oder ob man sagt "Das, was du gesagt hast, ist ja mal alles sowas von falsch und zeigt, dass du offensichtlich überhaupt keine Ahnung vom Programmieren hast". Ja, ich weiß, so krass hast du es nicht ausgedrückt. Aber ungefähr so kam es zumindest bei mir rüber. Mir ist klar, dass du deutlich mehr Erfahrung in der Programmierung hast, als ich und ich auch manchmal unbewusst Blödsinn verzapfe. Aber kannst du nicht versuchen, mich sachlich darauf hinzuweisen, anstatt dich als überlegen und mich als Idioten darzustellen? Und dass 95% der Programmierer auf mich arrogant wirken liegt sicher nicht daran, dass ich überhaupt etwas falsches sage, es liegt eher daran, dass diese 95% der Programmier so scheiße darauf reagieren, wenn mal jemand etwas falsches sagt. Ich kenne durchaus auch einige Programmierer, die deutlich besser sind als ich und mit denen ich mich trotzdem super verstehe, weil sie ihre Erfahrung vermitteln können, ohne dabei mit ihrer Überlegenheit zu prahlen. Und gleichzeitig bestätigt gerade mein Studium aber, dass es eben auch diverse Programmierer gibt, die gar nicht anders können, als mit ihrer Überlegenheit (oder gar Pseudo-Überlegenheit) zu prahlen. Zwar sind wir insgesamt nur 7 Programmierer im Jahrgang und davon nur 4 in meinem Kurs, aber gerade bei der geringen Menge fällt jeder eben umso mehr auf. So hat mich beispielsweise in der allerersten Woche ein Kollege total in den Boden geflamed, bloß weil ich gesagt habe - und ich zitiere - "Ach, Free Pascal ist gar nicht sooo schlecht". Daraufhin entbrannte eine Riesen-Diskussion und er wollte mir unbedingt unter die Nase reiben, dass Free Pascal scheiße und C++ das Tollste sei. Und auf meine Argumente, dass Free Pascal durchaus auch einige Vorteile gegenüer C++ biete, reagierte er nur umso bestürzter und war nichtmal mehr in der Lage, eine objektive Diskussion zu führen. Und das ist nun wirklich nicht der erste Fall, in dem irgendein Programmierer mir seine Überlegenheit reindrücken wollte und das wegen einer total unwichtigen und kleinen Sache. Also tut mir Leid, wenn ich in dieser Hinsicht überempfindlich reagiere, aber sowas kotzt mich einfach an und meine Erfahrung zeigt mir, dass an meiner Behauptung (mit den 95%) durchaus ein Fünkchen Wahrheit dran ist.

  20. #20
    Zitat Zitat von RPG Hacker Beitrag anzeigen
    Für dich als Programmierer hingegen gibt es in C# in der Nutzung erstmal keinen Unterschied zwischen Reference-Typen und Value-Typen, die werden alle wie letzterer verwendet. Was ich damit sagen will: Wenn du beispielsweise eine Funktion mit Parametern schreibst, macht es für dich keinen Unterschied, ob du einen int übergibst oder eine Klasse. C# wählt automatisch die bestmögliche Option für dich.
    Machts für dich keinen Unterschied mit einer Kopie oder dem Original zu arbeiten? Nie?

    Zitat Zitat von RPG Hacker Beitrag anzeigen
    So kannst du beispielsweise einen int niemals als Referenztyp[...] übergeben.
    Ref: http://msdn.microsoft.com/de-de/libr...=VS.80%29.aspx
    Out: http://msdn.microsoft.com/de-de/libr...=vs.80%29.aspx

    Nicht die empfohlenste Art in C# mit Parametern zu hantieren aber ganz praktisch.

    Zitat Zitat von RPG Hacker Beitrag anzeigen
    So kannst du beispielsweise [...]eine Klasse niemals als Valuetyp übergeben.
    Mach einen Clon O_o , es gibt Klassen, die akzeptieren ihre eigene Art im Konstruktor, wenn man es denn unbedingt einfach haben will, oder man schreibs sich selber kurz.
    Wenn das Ding eh nur Daten speichern soll mach 'n Struct draus.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •