programming language war



  • 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. 🙄



  • Jup, IntRaster und FloatRaster ist nicht sehr schön. Gibt es eigentlich Vorschläge diesbzgl. im JCP?



  • Optimizer schrieb:

    Gibt es eigentlich Vorschläge diesbzgl. im JCP?

    AFAIK nein. Aber es gibt einen Bug/RFE, der dieses Problem zum Thema hat:

    Bug-ID: 4487555

    Wenn dich das Problem sehr stört, dann kannst du ja mal für die Beseitigung dieses "Bugs" stimmen. Momentan hat der aber nur 60 Stimmen, er ist also weit davon entfernt, zu den relevantesten Bugs/RFEs gezählt zu werden.



  • auch wenn ich gleich weg geflamet werde, folgendes möchte ich mal kurz anmerken:

    Ich erinnere mich gut an eine Zeit wo Java Programmierer fest der Meinung waren, dass Templates sinnlos sind, weil man ja eh alles dynamisch machen kann 😉
    Und jetzt sind diese 'Generics' (wobei ich mich immer noch frage, warum man die so langsam machen hat müssen) 'godlike'.

    Strange, echt Strange.

    So, und nun happy flaming.



  • Es gab auch immer Java Programmierer die gerne Generics (Templates)
    haben wollten
    und:
    Es gibt immer noch Java Programmierer die nicht unbedingt generics
    wollen.

    Ich gehöre auch dazu.

    Jetzt kommen Sie, ok muss mich daran anpassen. Aber wie ich schon gesagt
    habe ich zumindest ein gutes Gefühl dabei das nicht die komplette VM
    deswegen umgeschrieben wird.

    Mann muss nicht immer alles Pauschalisieren.



  • Shade Of Mine schrieb:

    Ich erinnere mich gut an eine Zeit wo Java Programmierer fest der Meinung waren, dass Templates sinnlos sind, weil man ja eh alles dynamisch machen kann 😉
    Und jetzt sind diese 'Generics' (wobei ich mich immer noch frage, warum man die so langsam machen hat müssen) 'godlike'.

    Wie dir bestimmt schon aufgefallen ist, sind Generics keine Templates. Wenn ich hier davon rede, dass die Generics das Design eines Programms stark verändern, dann bezieht sich das in erster Linie auf Dinge wie Covarianz usw., die Teil der Generics sind. Bei Templates gibt es soetwas AFAIK nicht. Wenn sich die Generics auf die Funktionsweise von Templates beschränken würden, dann würden sie tatsächlich nur statische Typsicherheit bringen, was letztendlich nichts bringen würde, da die fehlende statische Typsicherheit noch nie Probleme bereitet hat (mir zumindest). Die Anwendbarkeit auf primitive Typen ist natürlich etwas, was die Templates bieten, die Generics aber nicht. Dies ist ein Nachteil der aktuellen Generics.

    Weiterhin ist es tatsächlich so, dass sich Generics in der aktuellen Form nicht sehr gut mit einigen anderen Java-Features wie z.B. Reflection vertragen. Bei allem Lob bezüglich der Generics gibt es also immer noch deutliche Schwachstellen.

    Abgesehen davon ist die AFAIK wichtigste Neuerung, die mit Java 1.5 kommt nicht das Vorhandensein von Generics, sondern das Vorhandensein der neuen Metadaten. Diese ermöglichen einen deklarativen Programmierstil, der einem wirklich viel Code ersparen kann (allerdings wohl nur im Großen).



  • Shade Of Mine schrieb:

    Ich erinnere mich gut an eine Zeit wo Java Programmierer fest der Meinung waren, dass Templates sinnlos sind, weil man ja eh alles dynamisch machen kann 😉
    Und jetzt sind diese 'Generics' (wobei ich mich immer noch frage, warum man die so langsam machen hat müssen) 'godlike'.

    Wie dir bestimmt schon aufgefallen ist, sind Generics keine Templates. Wenn ich hier davon rede, dass die Generics das Design eines Programms stark verändern, dann bezieht sich das in erster Linie auf Dinge wie Covarianz usw., die Teil der Generics sind. Bei Templates gibt es soetwas AFAIK nicht. Wenn sich die Generics auf die Funktionsweise von Templates beschränken würden, dann würden sie tatsächlich nur statische Typsicherheit bringen, was letztendlich nichts bringen würde, da die fehlende statische Typsicherheit noch nie Probleme bereitet hat (mir zumindest). Die Anwendbarkeit auf primitive Typen ist natürlich etwas, was die Templates bieten, die Generics aber nicht. Dies ist ein Nachteil der aktuellen Generics.

    Weiterhin ist es tatsächlich so, dass sich Generics in der aktuellen Form nicht sehr gut mit einigen anderen Java-Features wie z.B. Reflection vertragen. Bei allem Lob bezüglich der Generics gibt es also immer noch deutliche Schwachstellen.

    Abgesehen davon ist die AFAIK wichtigste Neuerung, die mit Java 1.5 kommt nicht das Vorhandensein von Generics, sondern das Vorhandensein der neuen Metadaten. Diese ermöglichen einen deklarativen Programmierstil, der einem wirklich viel Code ersparen kann (allerdings wohl nur im Großen).



  • Die Java Generics kann man AFAIK auch nicht mit den C++ Templates vergleichen, da es sich bei den Generics wohl nur um die Container Möglichkeit handelt (vector<T>) und so komplexe spielchen, wie ein Parser-Generator, LISP Interpreter und co lassen sich damit ja nicht machen.

    Aber diese ständigen Sprachvergleiche nerven. Ihr kommt ja eh nie zu einem Punkt.

    Mit Java programmiert man als guter Java Programmierer eh anders als ein guter C++ Programmierer mit C++ programmiert. Wobei viele Programmierer, da sie in Realität sich nicht auf solche spielchen einlassen können, einfach beide Stile in beiden Programmiersprachen verwenden. Das ist nicht weiter schlimm, am Ende kommt man doch zum Ziel.



  • kingruedi schrieb:

    Aber diese ständigen Sprachvergleiche nerven. Ihr kommt ja eh nie zu einem Punkt.

    aber wenigstens hat das geblubber ein klein wenig unterhaltungswert +g*



  • kingruedi schrieb:

    Mit Java programmiert man als guter Java Programmierer eh anders als ein guter C++ Programmierer mit C++ programmiert. Wobei viele Programmierer, da sie in Realität sich nicht auf solche spielchen einlassen können, einfach beide Stile in beiden Programmiersprachen verwenden.

    Verstehe ich nicht. Ich behaupte einfach mal, dass das so nicht möglich ist. Wenn du in einer der beiden Sprachen ausgiebig von Sprachfeatures Gebrauch machst, die in der anderen Sprache nicht vorhanden sind, dann kannst du deinen "Stil" nicht einfach so auf die andere Sprache übertragen.


Anmelden zum Antworten