programming language war



  • Ich denke du solltest es mit der Seite sein lassen.

    C++onrad schrieb:

    Hi!
    Da ich im Unterricht (und auch auf Tests 😉 ) meine Abneigung zu Java zum Ausdruck bringe
    .....
    über "C++ versus Java" zu schreiben - und das aber möglichst objektiv.

    Diese beiden Sätzen widersprechen sich. Wenn du eine Abneigung gegen Java hast,
    und ein C++ Fanatiker bist wirst du, und wenn du dich sonstwie anstrengst, keine
    Objektivität erreichen. Das geht nicht solange mann Programmiersprachen nicht nüchtern betrachtet.

    Ich könnte die Seite auch nicht erstellen, sie würde wohl auch nicht hundertprozentig objectiv sein, denn ich sehe viele Nachteile bei C++ die andere oft als Vorteil sehen.



  • Über so etwas einen Artikel schreiben kann nur jemand, der beide Sprachen gleichermaßen hasst.



  • Optimizer schrieb:

    Über so etwas einen Artikel schreiben kann nur jemand, der beide Sprachen gleichermaßen hasst.

    oder beide Sprachen gleich gut findet. Nur das gibt wohl nicht 😉



  • Magoon schrieb:

    Du solltest nicht eine Seite über Java versus c++ machen, sondern die verschiedenen Einsatzgebiete der Sprachen aufzählen. Gerade im betriebswirtschaftlichen Bereich hat Java seine stärken. Brauchst Du in einem Programm viel Performance, bzw. musst nah an die Maschine ran, dann nimm c oder c++.

    Deshalb frage ich mich immer noch, was J2ME auf Mobile Devices zu tun hat in der Spieleentwicklung. Schoen - funktioniert auf allen ein bischen, aber wirklich reissen kann man damit nichts, ausser man hat ein >= Serie 80 Phone, und da ist dann Symbian und C++ eh wieder besser.

    Was wirklich suckt an Java: Keine Enums, Keine Templates, Selbst mit Obfuscator viel zu grosse Archive, was auch an dem sch... Zip Format liegt, wenn man viele Files hat.

    P.S. und ja - ich hasse Java, auch wenn ich damit im Moment etwas verdiene 😉



  • SnorreDev schrieb:

    P.S. und ja - ich hasse Java, auch wenn ich damit im Moment etwas verdiene 😉

    Soso, du hasst also eine Sprache. SPricht nicht für deine Intelligenz. Naja, Fachinformatiker eben...

    @ C++onrad: Naja, bei dir ist die Sache recht einfach. Du bist ein Kind, dass jetzt etwas C++ kann und C++ natürlich cooler als Java findet. Da du noch nicht im Berufsleben stehst und somit die Praxistauglichkeit beider Sprachen noch nicht erlebt hast, sind deine Äußerungen bezüglich der Qualität der Sprachen sowieso unwichtig.



  • SnorreDev schrieb:

    Deshalb frage ich mich immer noch, was J2ME auf Mobile Devices zu tun hat in der Spieleentwicklung. Schoen - funktioniert auf allen ein bischen, aber wirklich reissen kann man damit nichts, ausser man hat ein >= Serie 80 Phone, und da ist dann Symbian und C++ eh wieder besser.

    Was ist besser?

    Was wirklich suckt an Java: Keine Enums,

    Java 1.5 🙂 Die haben wirklich gefehlt.

    Keine Templates

    Ich finde, dass die Generics das allermeiste mitbringen, was man in der Hinsicht braucht. Du nicht? Benutzt du noch 1.4? Selber schuld. Das einzige, was du für 1.5 brauchst, ist ein neuer Compiler.

    Selbst mit Obfuscator viel zu grosse Archive, was auch an dem sch... Zip Format liegt, wenn man viele Files hat.

    Kannst du das bitte genauer ausführen?? Ein fertig compiliertes C++ Programm ist um einiges größer als so ein Archiv. 😕

    P.S. und ja - ich hasse Java, auch wenn ich damit im Moment etwas verdiene 😉

    🙄



  • > Was ist besser?
    Symbian / C++ hat keine beschreankung der Archiv groesse und sehr viel schnellere Reaktionszeiten. Bei den neueren Devices ab Serie 80 wird's aber um einiges besser. MIDP 2 ist ein schritt in eine gute Richtung, und die Groesse des HEAP ist um einiges gewachsen, ebenso die groesse des Archives.

    > Ich finde, dass die Generics das allermeiste mitbringen, was man in der Hinsicht braucht. Du nicht? Benutzt du noch 1.4? Selber schuld. Das einzige, was du für 1.5 brauchst, ist ein neuer Compiler.
    Nicht ganz, ich nutze Java nur fuer Mobile Devices, also hilft mir ein Update auch nichts.

    > Kannst du das bitte genauer ausführen?? Ein fertig compiliertes C++ Programm ist um einiges größer als so ein Archiv. 😕
    Also wenn du dich nicht Tricks bedienst, wie z.B. die Tile's fuer ein Spiel in einem File zu Pagen, sondern lauter einzel Images ablegst, hast du nach zwanzig 16x16 Tiles schon 5 KB an Overhead, alleine durch das management vom Archiv. Da gibt's bessere Methoden, aber naja - es wurde ZIP verwendet, kann man nix dran aendern.

    > P.S. und ja - ich hasse Java, auch wenn ich damit im Moment etwas verdiene ;-)[/quote] 🙄[/quote]
    Bis auf bei normalen App's das Swing Packet, finde ich Java halt nicht wirklich toll. Das IO Handling nervt, die Punkte, die ich oben angesprochen habe auch.

    P.S. liegt wohl daran, dass ich ein alter Lowlevel Freak bin.

    @InfoStudent
    Geh wo anders trollen. Nicht mal noetig sich zu registrieren damit man weiss wer du bist, aber doof daherreden, sowas hamma gern!



  • SnorreDev schrieb:

    > Ich finde, dass die Generics das allermeiste mitbringen, was man in der Hinsicht braucht. Du nicht? Benutzt du noch 1.4? Selber schuld. Das einzige, was du für 1.5 brauchst, ist ein neuer Compiler.
    Nicht ganz, ich nutze Java nur fuer Mobile Devices, also hilft mir ein Update auch nichts.

    DAS ist mir nun wirklich nicht klar. Du weisst schon, dass du für 1.5 nicht mal eine andere VM brauchst? Du kannst die Generics praktisch als statische Typprüfung durch den Compiler betrachten, der anschließend wieder die gute alte Object-Klasse einsetzt.

    Wie das mit der I/O auf dem Handy ist, weiss ich ehrlich gesagt nicht. Auf jeden Fall finde ich die I/O Streams vom "normalen" Java für Desktop Systeme godlike. Keine Ahnung, ob das auf Handies anders gemacht wird.

    P.S. liegt wohl daran, dass ich ein alter Lowlevel Freak bin.

    Ja, das ist auch das Problem, das Microsoft bzgl. C# Sorgen macht. Ich war auf ein paar Seminaren von MS und die machen sich wirklich Sorgen, wie sie die Entwickler dazu bewegen können, von low-level und der WinAPI loszukommen. 🙂



  • Optimizer schrieb:

    DAS ist mir nun wirklich nicht klar. Du weisst schon, dass du für 1.5 nicht mal eine andere VM brauchst? Du kannst die Generics praktisch als statische Typprüfung durch den Compiler betrachten, der anschließend wieder die gute alte Object-Klasse einsetzt.

    Das ist falsch. "-source 1.5 -target 1.4" funktioniert mit dem aktuellen 1.5er javac nicht mehr. Mit anderen Worten: 1.5er Code läuft nicht auf früheren JVMs. (Der Code von früheren Java-Versionen läuft aber natürlich weiterhin auch mit einer 1.5er JVM.)



  • > DAS ist mir nun wirklich nicht klar. Du weisst schon, dass du für 1.5 nicht mal eine andere VM brauchst? Du kannst die Generics praktisch als statische Typprüfung durch den Compiler betrachten, der anschließend wieder die gute alte Object-Klasse einsetzt.<<
    Leider ist das auf Mobile Devices etwas anders, aber ich werde es sicher mal in meinem Picture Spider probieren, wenn ich wieder etwas mehr Luft habe.

    Wie das mit der I/O auf dem Handy ist, weiss ich ehrlich gesagt nicht. Auf jeden Fall finde ich die I/O Streams vom "normalen" Java für Desktop Systeme godlike. Keine Ahnung, ob das auf Handies anders gemacht wird. <<
    Ich meinte I/O auf Desktop Systemen. Ich finde es einfach Umstaendlich ueber die X Objekte und Klassen zu gehen, um einen Stream zu handlen. Ist aber wohl geschmackssache.
    Auf Handy's hast du weitaus schlechtere Moeglichkeiten. Da kannst du nur soetwas wie die Registry, in der du Objektname und Value zuordnen kannst, ansonsten musst du dich wie in OpenGL mit Herstellerspezifischen Sachen herumschlagen, was nicht immer zu vermeiden ist - siehe Nokia's FullCanvas, Vibra Funktionen usw.

    > Ja, das ist auch das Problem, das Microsoft bzgl. C# Sorgen macht. Ich war auf ein paar Seminaren von MS und die machen sich wirklich Sorgen, wie sie die Entwickler dazu bewegen können, von low-level und der WinAPI loszukommen. :)<<
    Kann ich verstehen, aber die aelteren, bleiben halt gerne auf dem Status, der nicht so weit vom den Grundlagen entfernt sind, und bauen sich lieber drumherumm alles selbst. Deshalb bin ich schon am ueberlegen, ob ich nicht auf Treiberentwicklung umschwenken sollte.

    P.S. J2ME mit MIDP / CLDC 1.0 haben nicht mal nen Stringtokenizer - sogar den musste ich mir selbst bauen 😉



  • P.S. J2ME mit MIDP / CLDC 1.0 haben nicht mal nen Stringtokenizer - sogar den musste ich mir selbst bauen 😉

    Siehste, deshalb bin ich gerne High-Level. 🙂
    Aber wirklich, die Java I/O ist doch nur noch godlike. Da jag ich mal schnell n Objekt durch ObjectOutputStream, noch durch nen GZIPOutputStream, schicks an ein Socket, auf dem andern Rechner kommt es an, dort entzip ich es und erstelle wieder ein Objekt draus (die passende .class Datei muss halt vorhanden sein).
    Oder ich les irgendwas anderes ein, schalte noch einen BufferedStream davor und noch mal ein StringTokenizer. So kann ich mit null Aufwand die einzelnen Worte auslesen. :p

    @Gregor: Ah, interressant, ist das schon länger so? Und warum ist das so? So weit ich weiss, werden die Generics-Daten in den .class Files immer noch wegersetzt.



  • Ja, das ist auch das Problem, das Microsoft bzgl. C# Sorgen macht. Ich war auf ein paar Seminaren von MS und die machen sich wirklich Sorgen, wie sie die Entwickler dazu bewegen können, von low-level und der WinAPI loszukommen.

    Damit habe ich absolut keine Probleme. Ich bin gerade auf dem Trip: scheiß auf Geschwindigkeit, bequemlichkeit Zählt. Ob jemand jetzt 50ns wartet, oder 4ms ist ihm doch total egal.
    Dafür geht meine Entwicklung wesentlich schneller, einfacher und sicherer voran.



  • Optimizer schrieb:

    @Gregor: Ah, interressant, ist das schon länger so? Und warum ist das so? So weit ich weiss, werden die Generics-Daten in den .class Files immer noch wegersetzt.

    Hier gibt es ein paar Informationen über das neue Class-File-Format. Zum Beispiel folgendes:

    The four planned updates are:

    * Adding split verifier support.

    The split verifier architecture that was introduced in CDLC via JSR-030 and JSR-139 offers significant improvements over the classic JVM verifier, including reducing verification time. It appears useful to allow this verification format to be used with J2SE.

    * Increasing various size limits.

    Some applications that automatically generate JavaTM source code (such as JSP compilers) have reported encountering problems due to implicit size limits in the current class file format. This JSR will increase relevant limits where needed.

    * Adding support for class literals.

    Since JDK 1.1 the JavaTM language has included support for accessing class literals though expressions such as "MyClassName.class". However there has been no direct support for this in the class file format and it appears that adding class file support will allow significantly more efficient access to class literals.

    * Minor changes to support JavaTM language changes in Tiger.

    The JavaTM language changes that are planned for Tiger do not require any major JavaTM virtual machine changes. However, there may be some minor changes such as adding additional classfile attributes or flag bits. These JVM specification changes will be handled through this JSR, after consultation with the specification leads for the relevant language JSRs.

    Ich denke aber, dass das nicht alle Veränderungen sind bzw., dass der vierte Punkt untertrieben ist. Beispielsweise werden jetzt auch die (ab 1.5 neuen) Metadaten teilweise in den Class-Dateien gespeichert.



  • Ich bin ja immer noch der Hoffnung, dass die Generics irgendwann doch ohne typecasts implementiert werden und primitive Typen ohne boxing supporten. Dann sind sie godlike. 🙂

    @Helium: Sehe ich in etwa genauso. Ich überleg mir lieber einen gescheiten Algorithmus, wenn die Performance schlecht ist. Damit komme ich eigentlich immer aus.



  • Optimizer schrieb:

    Ich bin ja immer noch der Hoffnung, dass die Generics irgendwann doch ohne typecasts implementiert werden und primitive Typen ohne boxing supporten. Dann sind sie godlike. 🙂

    Geht mir ähnlich, aber so schnell wird das wohl nichts. Aber ich habe inzwischen zumindest schon fest gestellt, dass die Generics doch mehr bringen als nur statische Typprüfung. Aus meiner Sicht wirken sie sich doch massiv auf das Design eines Programmes aus. Zusammen mit den Metadaten verändern sie die Art wie man Java programmiert doch gewaltig. ...zumindest bei mir. Insofern sehe ich es momentan so, dass eine Unterstützung von primitiven Typen durch die Generics zwar ein ganz nettes Zusatzfeature gewesen wäre aber, dass die neuen Sprachfeatures auch so schon eine ganze Menge bringen. Da ist eigentlich kein Grund da, sich zu beklagen.



  • Programmiertechnisch sind die Generics absolut top. Das möchte ich sicher nicht in Frage stellen. Aber ich frage mich schon ernsthaft, wie das mit der Performance ausschaut, wenn ich eine ArrayList<Integer> mache.
    Für jeden Zugriff habe ich boxing/unboxing und einen (unnötigen) checked typecast.
    Die Indexprüfung kommt auch noch hinzu, aber da bin ich gerne bereit, den Preis dafür zu zahlen. Aber das andere ist einfach unnötig, IMHO.



  • Optimizer schrieb:

    Die Indexprüfung kommt auch noch hinzu, aber da bin ich gerne bereit, den Preis dafür zu zahlen.

    Stehst wohl nicht auf Buffer Overflows? 🤡



  • Optimizer schrieb:

    Aber ich frage mich schon ernsthaft, wie das mit der Performance ausschaut, wenn ich eine ArrayList<Integer> mache.
    Für jeden Zugriff habe ich boxing/unboxing und einen (unnötigen) checked typecast.

    Die Performance sieht da mies aus! 😃 Allerdings ist das auch nicht sooo ein großes Problem. Für die paar Stellen im Programm, an denen man wirklich eine ausgezeichnete Performance benötigt, muss man dann halt ohne Generics und ohne das Collection-Framework auskommen. Dann muss man halt mal in den sauren Apfel beißen und sich einen Container für einen primitiven Typ programmieren. Es gibt AFAIK auch Seiten im Netz, wo man solche Container bekommt.



  • Sgt. Nukem schrieb:

    Optimizer schrieb:

    Die Indexprüfung kommt auch noch hinzu, aber da bin ich gerne bereit, den Preis dafür zu zahlen.

    Stehst wohl nicht auf Buffer Overflows? 🤡

    Manchmal schon... wenn ich meine SM-Phase habe. 😉

    Gregor schrieb:

    Dann muss man halt mal in den sauren Apfel beißen und sich einen Container für einen primitiven Typ programmieren. Es gibt AFAIK auch Seiten im Netz, wo man solche Container bekommt.

    Jup. Ich bins nur von Java gewohnt, dass ich gar nichts mehr selber machen muss. 😃
    Naja mal schaun, um ehrlich zu sein, war ich noch nicht in einer Situation, wo das ein Problem ist. Es geistert halt nur immer durch mein Hirn, dass da (verborgene) typechecks gemacht werden, die ja gerade durch die Generics unnötig werden sollten. 🤡



  • Optimizer schrieb:

    Naja mal schaun, um ehrlich zu sein, war ich noch nicht in einer Situation, wo das ein Problem ist.

    Ich ehrlich gesagt schon. Ich habe letzt erst folgende (bisher nicht fertige) Klassen geschrieben, die zumindest relativ performant sein müssen:

    package jaradap.model;
    
    public abstract class Raster<Type extends Number>
    {
       private final int [] size;
       private EdgeHandler edgeHandler;
       private final int [] locationMultipliers;
    
       protected Raster(final int... size)
       {
          if (size == null) throw new NullPointerException("size is null");
          if (size.length <= 0) throw new IllegalArgumentException("size.length <= 0");
          this.size = new int[size.length];
          for (int i = 0 ; i < size.length ; ++i)
          {
             if (size[i] < 0) throw new IllegalArgumentException("size[" + i + "] is negative.");
             this.size[i] = size[i];
          }
          locationMultipliers = new int[size.length];
          locationMultipliers[0] = 1;
          for(int i = 1 ; i < locationMultipliers.length ; ++i)
          {
             locationMultipliers[i] = locationMultipliers[i-1] * size[i-1];
          }
          edgeHandler = ExceptionEdgeHandler.getInstance();
       }
    
       public final int getDimensions()
       {
          return size.length;
       }
    
       public final int getSize(final int dimension)
       {
          return size[dimension];
       }
    
       public final EdgeHandler getEdgeHandler()
       {
          return edgeHandler;
       }
    
       public final void setEdgeHandler(final EdgeHandler handler)
       {
          if(handler == null) throw new NullPointerException("Edge handler is null.");
          edgeHandler = handler;
       }
    
       public final boolean resetEdgeHandler()
       {
          if (!(getEdgeHandler() instanceof ExceptionEdgeHandler))
          {
             setEdgeHandler(ExceptionEdgeHandler.getInstance());
             return true;
          }
          return false;
       }
    
       protected final int getElementIndex(final int... location)
       {
          if (location.length != getDimensions()) throw new IllegalArgumentException("Location and data have " + 
                                                            "different number of dimensions.");
          for (int i = 0 ; i < location.length ; ++i)
          {
             if(location[i] < 0) return -1;
             if(location[i] >= getSize(i)) return -1;
          }
          int elementNumber = location[0];
          for(int i = 1 ; i < location.length ; ++i)
          {
             elementNumber += getLocationMultiplier(i) * location[i];
          }
          return elementNumber;
       }
    
       protected final int getLocationMultiplier(final int dimension)
       {
          return locationMultipliers[dimension];
       }
    
       private static class ExceptionEdgeHandler implements EdgeHandler
       {
          private static final ExceptionEdgeHandler instance = new ExceptionEdgeHandler();
    
          private ExceptionEdgeHandler()
          {
          }
    
          public static ExceptionEdgeHandler getInstance()
          {
             return instance;
          }
    
          public int getElement(final IntRaster raster, int... location)
          {
             throw new IndexOutOfBoundsException("Location is out of bounds: " + location);
          }
    
          public float getElement(final FloatRaster raster, int... location)
          {
             throw new IndexOutOfBoundsException("Location is out of bounds: " + location);
          }
       }
    }
    
    package jaradap.model;
    
    public class IntRaster extends Raster<Integer>
    {
       private final int [] raster;
    
       public IntRaster (final int... size)
       {
          super(size);
          int elements = 1;
          for (int i = 0 ; i < getDimensions() ; ++i)
          {
             elements *= getSize(i);
          }
          raster = new int[elements];
       }
    
       public int getElement(final int... location)
       {
          final int index = getElementIndex(location);
          return (index >= 0) ? raster[index] : getEdgeHandler().getElement(this,location);
       }
    
       public boolean setElement(final int value, final int... location)
       {
          final int index = getElementIndex(location);
          if(index >= 0) 
          {
             raster[index] = value;
             return true;
          }
          return false;
       }
    
       public int getElementAt(final int index)
       {
          return raster[index];
       }
    
       public void setElementAt(final int value, final int index)
       {
          raster[index] = value;
       }
    
       public int getNumberOfElements()
       {
          return raster.length;
       }
    }
    
    package jaradap.model;
    
    public class FloatRaster extends Raster<Float>
    {
       private final float [] raster;
    
       public FloatRaster (final int... size)
       {
          super(size);
          int elements = 1;
          for (int i = 0 ; i < getDimensions() ; ++i)
          {
             elements *= getSize(i);
          }
          raster = new float[elements];
       }
    
       public float getElement(final int... location)
       {
          final int index = getElementIndex(location);
          return (index >= 0) ? raster[index] : getEdgeHandler().getElement(this,location);
       }
    
       public boolean setElement(final float value, final int... location)
       {
          final int index = getElementIndex(location);
          if(index >= 0) 
          {
             raster[index] = value;
             return true;
          }
          return false;
       }
    
       public float getElementAt(final int index)
       {
          return raster[index];
       }
    
       public void setElementAt(final float value, final int index)
       {
          raster[index] = value;
       }
    
       public int getNumberOfElements()
       {
          return raster.length;
       }
    }
    

    Du siehst: Durch dieses Problem kann ne Menge Redundanz entstehen. 🙄


Anmelden zum Antworten