The "C is Efficient" Language Fallacy



  • Basher schrieb:

    +fricky schrieb:

    scheint

    Wenn man keine Ahnung von C++ hat, dann "scheint" das so zu sein, ja.

    was wäre denn für dich ein plausibler grund?

    Basher schrieb:

    knivil schrieb:

    ...

    ...
    Aber da alle anderen schon auf den Artikel eingeprügelt haben und man sicherheitshalber einen Tag gewartet hat, ob noch was kommt, darf man ja unqualifiziert mit einstimmen

    übrigens machste deinem namen wieder mal alle ehre, lässt keine möglichkeit aus, jemanden dumm anzupöbeln.
    🙂



  • +fricky schrieb:

    was wäre denn für dich ein plausibler grund?

    Wenn dich C++ interessiert, informiere dich selbst. Ich werde das nicht für dich übernehmen.



  • Bashar schrieb:

    Wenn dich C++ interessiert, informiere dich selbst. Ich werde das nicht für dich übernehmen.

    sag doch gleich, dass du es nicht weisst.
    🙂



  • Es reicht doch, dass du es nicht weißt, aber trotzdem große Töne spuckst.



  • Tim schrieb:

    rüdiger schrieb:

    Und in C++0x wird restrict leider noch nicht einmal aufgenommen.

    Warum eigentlich? Da hat man so viel eingebaut, aber solch eine elementare Geschichte nicht? Zumal viele Compilerbauer das wohl (dank C99) eh in petto hätten. Wundert mich schon ein wenig.

    Ja, das wundert/enttäuscht mich auch. Einige Compiler bieten restrict ja schon in C++ an (GCC, Intel etc.).



  • rüdiger schrieb:

    maximAL schrieb:

    Allerdings wird in Java ja auf jeden nicht-primitiven Typen per Referenz zugegriffen, was das Problem gegenüber C++ wieder verstärkt.

    Das ist egal. Wichtig ist nur, dass der Compiler über die Referenzen viel strengere Annahmen treffen darf, als ein C- oder C++-Compiler über die Pointer/Referenzen.

    Begründung? In Java gibts zwar kein Aliasing mit unterschiedliche Typen, aber nichtsdestotrotz können durchaus mehrere Referenzen in einem Kontext auf das selbe Objekte verweisen, was die Arbeit für den Compiler erschwert.



  • maximAL schrieb:

    In Java gibts zwar kein Aliasing mit unterschiedliche Typen, aber nichtsdestotrotz können durchaus mehrere Referenzen in einem Kontext auf das selbe Objekte verweisen, was die Arbeit für den Compiler erschwert.

    einen grossteil der optimierung macht die java-VM zur laufzeit, nicht der compiler. damit hat Java natürlich sehr viel mehr optimiermöglichkeiten, als programmiersprachen, deren compiler starren maschinencode für bestimmte CPUs erzeugen müssen. http://en.wikipedia.org/wiki/Java_performance#Adaptive_optimization
    🙂



  • maximAL schrieb:

    Begründung? In Java gibts zwar kein Aliasing mit unterschiedliche Typen, aber nichtsdestotrotz können durchaus mehrere Referenzen in einem Kontext auf das selbe Objekte verweisen, was die Arbeit für den Compiler erschwert.

    Worum es geht ist, dass

    while(*a++=*b++);

    nicht parallelisierbar ist.

    das problem hast du in java nicht.


  • Administrator

    maximAL schrieb:

    Begründung? In Java gibts zwar kein Aliasing mit unterschiedliche Typen, aber nichtsdestotrotz können durchaus mehrere Referenzen in einem Kontext auf das selbe Objekte verweisen, was die Arbeit für den Compiler erschwert.

    Hmmm, kenne mich zwar nicht so gut aus, aber wenn ich nach dem Wikipedia Artikel gehe, dann steht als Beispiel dies hier:

    void foo(int* lhs, int* rhs, int* val)
    {
      *lhs += *val;
      *rhs += *val;
    }
    

    Problem ist ja, dass lhs und val auf das gleiche Verweisen können. Also muss der Wert von val neu geladen werden, bevor die nächste Rechnung durchgeführt werden kann.

    Bei Java sieht dies allerdings etwas anders aus:

    public void foo(int lhs, int rhs, int val)
    {
      lhs += val;
      rhs += val;
    }
    

    val wird hier unverändert bleiben, egal wie man die Funktion aufruft.

    Würde das aber gerne noch bestätigt bekommen, bin mir nicht sicher, ob ich es ganz getroffen habe 🙂

    Grüssli



  • Dravere schrieb:

    maximAL schrieb:

    Begründung? In Java gibts zwar kein Aliasing mit unterschiedliche Typen, aber nichtsdestotrotz können durchaus mehrere Referenzen in einem Kontext auf das selbe Objekte verweisen, was die Arbeit für den Compiler erschwert.

    Hmmm, kenne mich zwar nicht so gut aus, aber wenn ich nach dem Wikipedia Artikel gehe, dann steht als Beispiel dies hier:

    void foo(int* lhs, int* rhs, int* val)
    {
      *lhs += *val;
      *rhs += *val;
    }
    

    Problem ist ja, dass lhs und val auf das gleiche Verweisen können. Also muss der Wert von val neu geladen werden, bevor die nächste Rechnung durchgeführt werden kann.

    Bei Java sieht dies allerdings etwas anders aus:

    public void foo(int lhs, int rhs, int val)
    {
      lhs += val;
      rhs += val;
    }
    

    val wird hier unverändert bleiben, egal wie man die Funktion aufruft.

    Würde das aber gerne noch bestätigt bekommen, bin mir nicht sicher, ob ich es ganz getroffen habe 🙂

    Grüssli

    Abgesehen davon, dass dein Java Beispiel semantisch etwas völlig anderes tut, ja.



  • In java sind ints genau so wenig Referenztypen, das Verhalten ist also genau das selbe, wie wenn du in C++ die ints per Val übergibst.
    Wenn du Referenztypen aus Java nimmst können die dann aber wiederum auch auf das selbe zeigen.


  • Administrator

    JustAnotherNoob schrieb:

    In java sind ints genau so wenig Referenztypen, das Verhalten ist also genau das selbe, wie wenn du in C++ die ints per Val übergibst.
    Wenn du Referenztypen aus Java nimmst können die dann aber wiederum auch auf das selbe zeigen.

    Ich muss zugeben, dass mein Java völlig eingerostet ist, aber wenn ich es korrekt in Erinnerung hatte, dann wird hier nicht per Value übergeben sondern per Referenz. Intern bei der Addition wird das Ergebnis nicht in die referenzierte Variable geschrieben, sondern eine neue erstellt und diese dann der Referenz zugewiesen. Die Referenzen lhs und rhs werden also in der Funktion auf zwei neue Variablen gesetzt und zwar jeweils nach der Addition.

    Das gleiche gilt dann auch bei anderen Objekten in Java wie zum Beispiel java.lang.String . Bei jeder Veränderung wird einem gleich ein neues Objekt zurückgeliefert. Die Veränderungen werden also nicht auf dem Objekt selbst durchgeführt.

    Kann gut sein, dass ich hier völlig auf dem Holzweg bin, wie gesagt, mein Java ist eingerostet. Würde mich aber freuen, wenn mich da jemand korrigieren könnte, falls ich falsch liege.

    Grüssli



  • aber wenn ich es korrekt in Erinnerung hatte, dann wird hier nicht per Value übergeben sondern per Referenz.

    http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html
    -> nein, das wird nicht als Referenz übergeben.

    String ist nochmal ein Sonderfall, weil es ein Objekt ist, dass von Literalen erzeugt wird, aber normale Objekte können durchaus aufeinander verweisen, mit

    Object a = new Object();
    Object b = a;
    

    verweist b afaik auf a.



  • Dravere schrieb:

    JustAnotherNoob schrieb:

    In java sind ints genau so wenig Referenztypen, das Verhalten ist also genau das selbe, wie wenn du in C++ die ints per Val übergibst.
    Wenn du Referenztypen aus Java nimmst können die dann aber wiederum auch auf das selbe zeigen.

    Ich muss zugeben, dass mein Java völlig eingerostet ist, aber wenn ich es korrekt in Erinnerung hatte, dann wird hier nicht per Value übergeben sondern per Referenz. Intern bei der Addition wird das Ergebnis nicht in die referenzierte Variable geschrieben, sondern eine neue erstellt und diese dann der Referenz zugewiesen. Die Referenzen lhs und rhs werden also in der Funktion auf zwei neue Variablen gesetzt und zwar jeweils nach der Addition.

    Das gleiche gilt dann auch bei anderen Objekten in Java wie zum Beispiel java.lang.String . Bei jeder Veränderung wird einem gleich ein neues Objekt zurückgeliefert. Die Veränderungen werden also nicht auf dem Objekt selbst durchgeführt.

    Kann gut sein, dass ich hier völlig auf dem Holzweg bin, wie gesagt, mein Java ist eingerostet. Würde mich aber freuen, wenn mich da jemand korrigieren könnte, falls ich falsch liege.

    Grüssli

    Java ist wie C und C++ auch "call by Value", sprich die Parameter werden immer kopiert. In Java werden die primitiven Typen aber auch wie in C und C++ gehandhabt und nicht wie die Java-Objekte (beidenen ist nur Zugriff über Zeiger möglich).


  • Administrator

    JustAnotherNoob schrieb:

    http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html
    -> nein, das wird nicht als Referenz übergeben.

    In dem Link steht dazu allerdings nichts 😉
    In meinen Vorlesungsnotizen allerdings schon und zwar genau so, wie ich es gesagt hatte. Würde mich aber nicht erstaunen, wenn dies falsch ist. Wäre ja typisch, geht genau gleich zu wie in C++

    Naja, dachte ich hätte es womöglich begriffen, aber das ist wohl definitiv nicht der Fall. Muss ich mich da nochmals ein wenig reinarbeiten. Danke jedenfalls.

    Grüssli



  • In dem Link steht dazu allerdings nichts

    ups, ist aber trotzdem richtig - probiers aus.



  • Java ist ausschließlich call-by-value. Bei Objekt-Typen werden Referenzen eben by-value übergeben. Call-by-reference ist was völlig anderes.



  • Java hat sogar nur Call By Value - ein Call By Reference gibt es garnicht 🙄



  • Shade Of Mine schrieb:

    Java hat sogar nur Call By Value - ein Call By Reference gibt es garnicht 🙄

    Das mag sein, aber für den Anwender erscheint es bei Objekten anders (Wie es konkret umgesetzt wird, interessiert Viele nicht, sofern sie das Ergebnis verstehen).



  • asc schrieb:

    Das mag sein, aber für den Anwender erscheint es bei Objekten anders (Wie es konkret umgesetzt wird, interessiert Viele nicht, sofern sie das Ergebnis verstehen).

    void recreate(String s) {
      s=new String("recreated");
    }
    

    Das ist Call By Value. Und das ist kein verstecktes detail. Deshalb gibt es ja auch zB das idiom des object wrappers um call by reference zu ermoeglichen:

    class StringWrapper {
    public StringWrapper(String value) {
      this.value = value;
    }
      public String value;
    };
    
    void recreate(StringWrapper s) {
      s.value=new String("recreated");
    }
    

Anmelden zum Antworten