C oder C++?



  • Optimizer schrieb:

    Außerdem können Strings im Gegensatz zu StringBuffers geshared werden.
    String a = b;
    bewirkt nur die Kopie eines Zeigers. So einfach kannst du das in C++ bestenfalls mit der Copy-on-write Technik erreichen, die einigermaßen aufwändig zu implementieren ist und auch Overhead erzeugt.

    Wozu? Java macht doch auch kein Copy-On-Write, wozu soll ich das also machen? Sind ja 2 verschiedene Sachen. Ich share einfach auch das Objekt:

    shared_ptr<string> p(new string("hallo"));
    shared_ptr<string> p2(p);

    🙂

    Btw. die std::string implementierung von meinem Compiler nutzt diese Vorgehensweise nicht, da wird wirklich jedesmal der String kopiert.

    Sehr kluge entscheidung des Herstellers.

    Was genau ist umständlicher, besonders in Bezug auf I/O und im speziellen File I/O ?

    EOF ist eine Exception?
    Ich muss BufferedReader, Writer und sonstwas erstellen.
    Also gerade IO gefällt mir in Java weniger gut.

    Aber deine Begründungen, warum Java überhaupt keine Existenzberechtigung hat, ist IMO nicht nachvollziehbar.

    wo hat er das gesagt?



  • JUHUUUUUUU

    FLAMEWAR

    EOF ist eine Exception?
    Ich muss BufferedReader, Writer und sonstwas erstellen.
    Also gerade IO gefällt mir in Java weniger gut.

    das mit eof geb ich dir - das hatten wir schon mal an anderer stelle.

    hier sei angeführt das java einen anderen ansatz zur dateibearbeitung hat als alles das ich kenne. es gibt das file (quasi der pointer auf die file structur in gutem alten C), die streams zum einlesen und auslesen und den reader und writer (schreiben und lesen)
    das alles macht es universell auf allen plattformen einsetzbar ohne das man an der implementierung was ändern müsste

    man hat ausserdem wesentlich mehr möglichkeiten verschiedenste dinge objekt orientiert zu schreiben

    also ich mag das - auch wenn es mehr aufwand als in C++ ist

    ich würde Real nicht so abtun, er hat halt keine lust sich wo einzuarbeiten und hat sicher viele vorurteile die auch andere haben
    aber wenn es nicht sein bier ist soll er halt mit C schreiben
    wenns wirklich tief runtergehen soll empfehle ich assembler
    da gehts dann rund

    gomberl



  • Hi Optimizer,
    gut, den Unterschied zwischen String und StringBuffer kennst du ja. Viele Java-Programmierer sehen genau das als Nachteil.
    String wird bei einer Anhänung nicht verändert, wie viele meinen, sondern es wird ein neues Objekt erstellt. Bei kurzen Sachen mag das ok sein, aber bei vielen Anhängungen und langen Liste tendiere ich zu StringBuffer.

    Optimizer schrieb:

    Kommt drauf an! Wenn du eine fette Liste zusammnhängender Strings ausgibst, ist String um ein vielfaches langsamer als StringBuffer.
    Ich hab´s mal in einer Schleife probiert. String braucht über eine Minute und StringBuffer nur wenige Sekunden (unter 5). Wieviele String ich angehängt habe und wie oft die Schleife durchloffen worden ist, weiss ich nicht mehr, aber probier´s am Besten selbst aus

    Ist nicht langsamer. Der Sourcecode würde mich interressieren. Es hat dir ja keiner gesagt, dass du '+' benutzen sollst, um mehrere Strings auszugeben (wie gesagt, '+' ist über StringBuffer implementiert).
    Mehrere print's erfüllen genau den selben Zweck.

    Leider weiss ich nicht, wie ich bei Strings das "+" umgehen kann.
    Hier poste hier mal den kompletten Code, so dass du das Programm ausprobieren kannst. Es war eine kleine Hausaufgabe, wo man den Preis eingibt und die Jahre in denen man das Produkt abbezahlen will.
    Ersetze alle StringBuffer mit String und gib mal bei Preis= 10000 und Jahre=10 000 000. Mit StringBuffer kannst du sogar höhere Werte eingeben und es wird trotzdem deutlich schneller sein als String. Klar, das Beispiel mag etwas übertrieben sein, aber es zeigt einem deutlich den Gewschindigkeitsvorteil von StringBuffer.

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.io.*;
    
    public class HauptFenster extends JFrame {
      JPanel contentPane;
      TextField tfPreis = new TextField();
      Label lbPreis = new Label();
      TextField tfJahre = new TextField();
      Label lbJahre = new Label();
      Button btBerechnen = new Button();
      Button btSpeichern = new Button();
      TextArea taKapital = new TextArea();
      Button btLoeschen = new Button();
      Label lbStatus = new Label();
      StringBuffer kapitalAusgabe = new StringBuffer(); //Instanzvariable
      Button btLesen = new Button();
      JMenuBar jMenuBar = new JMenuBar();
      JMenu jMDatei = new JMenu();
      JMenuItem jMSchliessen = new JMenuItem();
    
      /**Den Frame konstruieren*/
      public HauptFenster() {
        enableEvents(AWTEvent.WINDOW_EVENT_MASK);
        try {
          jbInit();
        }
        catch(Exception e) {
          e.printStackTrace();
        }
      }
    
      /**Initialisierung der Komponenten*/
      private void jbInit() throws Exception  {
        //setIconImage(Toolkit.getDefaultToolkit().createImage(HauptFenster.class.getResource("[Ihr Symbol]")));
        contentPane = (JPanel) this.getContentPane();
        contentPane.setLayout(null);
        this.setJMenuBar(jMenuBar);
        this.setSize(new Dimension(400, 346));
        this.setTitle("Produkt-Abbezahlung");
        tfPreis.setBounds(new Rectangle(227, 42, 108, 32));
        lbPreis.setFont(new java.awt.Font("Dialog", 1, 12));
        lbPreis.setText("Preis in €");
        lbPreis.setBounds(new Rectangle(228, 15, 56, 25));
        tfJahre.setBounds(new Rectangle(228, 104, 108, 32));
        lbJahre.setBounds(new Rectangle(221, 77, 123, 25));
        lbJahre.setText("Abbezahlung in Jahre");
        lbJahre.setFont(new java.awt.Font("Dialog", 1, 12));
        btBerechnen.setBackground(Color.white);
        btBerechnen.setFont(new java.awt.Font("Dialog", 1, 12));
        btBerechnen.setLabel("Berechnen");
        btBerechnen.setBounds(new Rectangle(234, 156, 99, 35));
        btBerechnen.addActionListener(new java.awt.event.ActionListener() {
          public void actionPerformed(ActionEvent e) {
            btBerechnen_actionPerformed(e);
          }
        });
        btSpeichern.addActionListener(new java.awt.event.ActionListener() {
          public void actionPerformed(ActionEvent e) {
            btSpeichern_actionPerformed(e);
          }
        });
        btSpeichern.setBounds(new Rectangle(18, 214, 99, 35));
        btSpeichern.setLabel("Speichern");
        btSpeichern.setFont(new java.awt.Font("Dialog", 1, 12));
        btSpeichern.setBackground(Color.white);
        taKapital.setEditable(false);
        taKapital.setBounds(new Rectangle(8, 20, 202, 172));
        btLoeschen.addActionListener(new java.awt.event.ActionListener() {
          public void actionPerformed(ActionEvent e) {
            btLoeschen_actionPerformed(e);
          }
        });
        btLoeschen.setBounds(new Rectangle(75, 255, 99, 35));
        btLoeschen.addMouseListener(new java.awt.event.MouseAdapter() {
        });
        btLoeschen.setLabel("Löschen");
        btLoeschen.setFont(new java.awt.Font("Dialog", 1, 12));
        btLoeschen.setBackground(Color.white);
        lbStatus.setBounds(new Rectangle(190, 260, 130, 33));
        btLesen.setBackground(Color.white);
        btLesen.setFont(new java.awt.Font("Dialog", 1, 12));
        btLesen.setLabel("Auslesen");
        btLesen.setBounds(new Rectangle(128, 214, 99, 35));
        btLesen.addActionListener(new java.awt.event.ActionListener() {
          public void actionPerformed(ActionEvent e) {
            btLesen_actionPerformed(e);
          }
        });
        jMDatei.setText("Datei");
        jMSchliessen.setText("Schließen");
        jMSchliessen.addMouseListener(new java.awt.event.MouseAdapter() {
          public void mousePressed(MouseEvent e) {
            jMSchliessen_mousePressed(e);
          }
        });
        contentPane.add(tfPreis, null);
        contentPane.add(lbPreis, null);
        contentPane.add(tfJahre, null);
        contentPane.add(lbJahre, null);
        contentPane.add(btBerechnen, null);
        contentPane.add(btSpeichern, null);
        contentPane.add(taKapital, null);
        contentPane.add(lbStatus, null);
        contentPane.add(btLesen, null);
        contentPane.add(btLoeschen, null);
        jMenuBar.add(jMDatei);
        jMDatei.add(jMSchliessen);
      }
      /**Überschrieben, so dass eine Beendigung beim Schließen des Fensters möglich ist.*/
      protected void processWindowEvent(WindowEvent e) {
        super.processWindowEvent(e);
        if (e.getID() == WindowEvent.WINDOW_CLOSING) {
          System.exit(0);
        }
      }
    
      void btBerechnen_actionPerformed(ActionEvent e) {
    
    if(tfPreis.getText().equals("") || tfJahre.getText().equals(""))
    {
    JOptionPane.showMessageDialog(this,"Bitte Textfelder komplett ausfüllen!");
    }
    
    else
    {
      double preis, jahre, kapital;
      preis=Double.parseDouble(tfPreis.getText());
      jahre=Double.parseDouble(tfJahre.getText());
    
      kapital=(preis/jahre);
    
      int jahreUmrechnung = (int) jahre; //in int umwandeln
    
      kapitalAusgabe=new StringBuffer(""); //Automatisches Löschen, wenn man z.B. gleich danach nochmal etwas rechnet
    
      for(int i=1; i<= jahreUmrechnung; i++)
      {
       preis= preis-kapital;
       kapitalAusgabe= kapitalAusgabe.append(i).append(". Jahr: ").append(preis).append(" € \n");
        if(preis < kapital && preis !=0)
        {
        preis=0;
        kapitalAusgabe= kapitalAusgabe.append(i+1).append(". Jahr: ").append(preis).append(" € \n");
        }
      }
      taKapital.setText("Sie zahlen jährlich "+kapital+" € \n"+kapitalAusgabe.toString());
      }
      }
      void btSpeichern_actionPerformed(ActionEvent e) {
      if(taKapital.getText().equals(""))
      {
      JOptionPane.showMessageDialog(this,"TextArea noch leer");
      }
      else
      {
          try
        {
        BufferedWriter daten= new BufferedWriter(
        new FileWriter ("kapital.txt", true));
    
        daten.write(kapitalAusgabe.toString());
        daten.newLine();
        daten.write("________________________");
        daten.newLine();
        daten.close();
        JOptionPane.showMessageDialog(this, "Speichern war erfolgreich!");
        }
        catch(IOException f)
          {
          JOptionPane.showMessageDialog(this,"Fehler beim Speichern");
          }
        }
      }
      void btLoeschen_actionPerformed(ActionEvent e) {
      //Kleiner (blinkender) Gag eingebaut :-)
      try{
        lbStatus.setText("Wird gelöscht...");
        btLoeschen.setBackground(Color.red);
        Thread.sleep(500);
        btLoeschen.setBackground(Color.white);
        Thread.sleep(500);
        btLoeschen.setBackground(Color.red);
        Thread.sleep(500);
        btLoeschen.setBackground(Color.white);
        lbStatus.setText("Gelöscht!");
        taKapital.setText("");
        Thread.sleep(1500);
        lbStatus.setText("");
      }
      catch(InterruptedException fx)
        {
        JOptionPane.showMessageDialog(this,"Fehler!");
        }
      }
      void btLesen_actionPerformed(ActionEvent e) {
    
      try
      {
      BufferedReader daten= new BufferedReader(
      new FileReader("kapital.txt"));
    
      String line=daten.readLine();
    
      kapitalAusgabe=new StringBuffer(daten.readLine()).append("\n");
      while(line!=null)
        {
        kapitalAusgabe=kapitalAusgabe.append(line).append("\n");
        line=daten.readLine();
        }
      taKapital.setText(kapitalAusgabe.toString());
      daten.close();
      }
      catch(IOException fx)
        {
        JOptionPane.showMessageDialog(this, "\"kapital.txt\" nicht vorhanden");
        }
    
      }
    
      void jMSchliessen_mousePressed(MouseEvent e) {
      System.exit(0);
      }
    }
    

    Was genau ist umständlicher, besonders in Bezug auf I/O und im speziellen File I/O ?

    Bei Eingabe und Ausgabe ist erst mal try/catch Pflicht, auch wenn die Anwedung noch so simpel ist. Bei größeren Projekten mag das zwar Sinn ergeben, aber das möchte ich schon selbst entscheiden. Dann brauche ich noch InputStreamReader und BufferedReader und dann kann´s mit dem .readLine() Befehl los gehen.
    Bei C++ braucht man nur eine Variable und Tschink (cin>>) kann´s losgehen. 😃

    Für mich persönlich sprechen ein paar sprachliche Beschränkungen gegen Java. Zum Glück kommen jetzt bald Generics. Ich vermisse Templates (homogene Container), const-correctness, Referenzen auf primitive Typen und Operator overloading, zumindest bei allen Operatoren außer '==', '!=' und offizielle Unterstützung für DirectX (die auch nie kommen wird).

    Sagt mir nicht viel, da ich momentan nur marginale Kenntnisse über C/C++ habe. Ich hörte ebenfalls eine Beschwerde von einem C++-Programmierer, dass bei Java die Grenze bei GUI schnell erreicht ist (bzw. bei Swing). Ein Klassenkamerad von mir, der zuvor in VB programmierte, reklamierte, dass er keine Möglichkeit sieht, die von der Datenbank erhalten Informationen in Tabellen darstellen lassen zu können.

    Aber deine Begründungen, warum Java überhaupt keine Existenzberechtigung hat, ist IMO nicht nachvollziehbar.

    Niemals behauptet.
    Ich sehe in Java ebenfalls viele Vorteile, es kann sogar sehr viel Geld mit Java eingespart werden wegen seiner Plattformunabhängigkeit, aber genau diese Vorteile sind bei mir nicht von großer Interesse (momentan zumindest nicht, vielleicht kommt die Zeit, wo ich das schätzen werde.)

    @Shade of Mind:
    Aus einem anderen Forum:

    ....
    Geht es ums lernen würde ich eher zu C raten. Warum?
    Meiner Meinung nach sollte man die Grundlagen können, bevor man sich mit irgendwas "höherem" beschäftigt. D.h. man sollte mal selber mit Zeigern gearbeitet haben, die Bits einzeln verschieben und Speicher von Hand belegt und freigegeben haben bevor man sich solchen Hilfsmitteln wie new, delete,... bedient, einfach um ein Bild davon zu haben was hinter den Kulissen vorgeht.

    Liebe Grüße
    Real

    PS: Deine Antwort fand ich jetzt gut! 🙂



  • Optimizer schrieb:

    Ich vermisse [...] offizielle Unterstützung für DirectX (die auch nie kommen wird).

    Ohhhh jaaa... *seufz*

    Shade Of Mine schrieb:

    Ich muss BufferedReader, Writer und sonstwas erstellen.
    Also gerade IO gefällt mir in Java weniger gut.

    Ich find' das eigentlich sehr gut.
    Ich kann so lowlevel runter wie ich will und so highlevel wie ich will (indem ich einfach mehrere InputStream/Reader-Objekte in die Pipeline schmeisse), und das sehr komfortabel. Kann also den Stream byte-weise auslesen, mir noch einen Reader davor knallen, z.B. LineNumberReader (für komfortable ReadLine() Aufrufe), den auch noch puffern mit Buffered..., und das sowohl als Zeichenstreams und Binärstreams. Am Ende jage ich noch alles durch einen Tokenizer und schwupps.
    Allerdings wirkt die IO API am Anfang ziemlich overbloated und man fühlt sich ziemlich erschlagen, das ging mir auch so.



  • Hi gomberl,

    gomberl schrieb:

    ich würde Real nicht so abtun, er hat halt keine lust sich wo einzuarbeiten und hat sicher viele vorurteile die auch andere haben
    aber wenn es nicht sein bier ist soll er halt mit C schreiben
    wenns wirklich tief runtergehen soll empfehle ich assembler
    da gehts dann rund

    in der Schule bin ich in Java am weitesten, ich würde mich gerne weiter einarbeiten, aber ich bin etwas demotiviert! Ich kann zwar das Gelernte umsetzen, aber nur irgendwelche Klassen aufzurufen, das mir dies und das erledigt ist für einen Anfänger nicht das wahre, da ich gerne kapieren will was da vorsichgeht!

    Ein anderer Grund, was mich demotiviert ist eben, dass Java nicht hardwarenah ist und man nicht richtig Systemprogrammierung praktzieren kann. Mit Aufrufen von externen Programmen und Anbindung fremder Programme die in anderen Sprachen implementiert wurden, kann man sich zwar etwas durchmogeln, aber dann ist auch schon der größte Lebenssin von Java futsch- die Plattformunahängigkeit (und die ist mir momentan soetwas von Wurst!).
    Wenn ich Ansi-C(++) verwende und da es portabel ist, muss es nur noch in einem anderen Compiler des jeweiligen System schmeissen und alles geht, ohne das etwas meckert (ausser man proggt eben systemspezifisch oder hardwarenah).

    Liebe Grüße
    Real



  • Ob man jetzt new schreibt oder malloc (in C), ist ja egal und du wirst in jedem
    C++ Lehrbuch am Anfang zuerst einmal all das kennen lernen was C auch kann.
    Nimm dir z.B. den C++ Primer der behandelt zuerst prozedurale Programmierung,
    Objektbasierte Programmierung und erst zum Schluss Objektorientierte Programmierung.



  • Warum sollte ein gutes C++-Buch die C-IO-Funktionen erklären? Und irgendeine Möglichkeit für die Ein-/Ausgabe wird man als Anfänger schnell brauchen. Da kann man auch mit den IOStreams klein anfangen. Ob man nun printf oder cout benutzt ohne es zu verstehen, ist ja eigentlich kein Unterschied - nur, dass man mit cout weniger Fehler machen kann.



  • Shade schrieb:

    Wozu? Java macht doch auch kein Copy-On-Write, wozu soll ich das also machen? Sind ja 2 verschiedene Sachen. Ich share einfach auch das Objekt:

    shared_ptr<string> p(new string("hallo"));
    shared_ptr<string> p2(p);

    Is vielleicht nicht rübegekommen. Wenn du std::strings sharest, hast du wohl das Problem:

    string a = "gduksfkszhdug"
    string b = a;   // ANGENOMMEN, buffer würde geshared
    a  +=  "öoisufg";  // oh SHIT, jetzt hab sich b auch geändert!
    

    Das hast du doch bei nem shared_ptr auch?
    Das könnte dann man mit copy-on-write lösen (wie gesagt). Ist aber IMHO immer noch nicht halb so elegant (das ist IMO ein ziemlicher Aufwand) wie immutable Strings.
    Dazu kommt noch hinzu, dass mir das in Java gefällt:

    "Mein String-Literal"  // Ist kein char*, kein char[] sondern ein String   :)
    "Mein String-Literal".length  // funktioniert
    

    Gut, das ist Spielerei, aber ich finde es schön. Vor allem, weil es nicht ineffizienter ist, da wird nichs konstruiert, ein String is ja nur ein Zeiger auf einen immutable Buffer. Wichtig ist es natürlich nicht, aber es gibt ja eigentlich auch keinen Grund, mit Pointern zu hantieren. 😃

    Übrigens: EOF ist AFAIK keine Exception, sondern das Ende wird mit einem negativem Wert angezeigt. Nur wenn du dann noch weiter liest, gibt's ne Exception. Bin mir jetzt nicht mehr 100% sicher, aber ich glaub das war so.

    Was hast du dagegen, einen Reader oder Writer zu erstellen? Ein new Aufruf, und du musst nicht mal an ein delete denken. 😉

    // Muss jetzt so nicht korrekt sein:
    BufferedReader a = new BufferedReader(new InputStream());
    

    Wenn dich des "Buffered" stört, dann musst du ihn ja nicht buffern.

    @Real: ja lol, du benutzt überall append(), wenn du da Strings hernimmst, müssen die erstmal in StringBuffer konvertiert werden. Du hast also nicht Strings mit StringBuffer verglichen. Wo ist denn jetzt genau das Problem, mehrere Strings nacheinander auszugeben?
    Und wenn du sie unbedingt konkatenieren willst, dann mach das alles in einer Anweisung mit '+', dann legt die VM gleich einen großen StringBuffer an und haut blitzschnell alles rein.



  • Ok die C Lib wird meist nicht wirklich behandelt, höchstens Teile davon, aber
    für jeden fortgeschrittenen Anfänger sollte es kein Problem sein, sich anhand
    einer Doku die Informationen holen die er benötigt um z.B. printf() zu benutzen.
    Oft reicht auch bereits nur ein Blick auf die deklaration der Funktion.



  • Real schrieb:

    Ich kann zwar das Gelernte umsetzen, aber nur irgendwelche Klassen aufzurufen, das mir dies und das erledigt ist für einen Anfänger nicht das wahre, da ich gerne kapieren will was da vorsichgeht!

    Wenn du wissen willst, was da vor sich geht, dann empfehle ich dir, ein Buch über Rechnerarchitektur usw. zu lesen. Da erfährst du mehr, als wenn du C lernst.



  • gomberl schrieb:

    JUHUUUUUUU

    FLAMEWAR

    EOF ist eine Exception?
    Ich muss BufferedReader, Writer und sonstwas erstellen.
    Also gerade IO gefällt mir in Java weniger gut.

    das mit eof geb ich dir - das hatten wir schon mal an anderer stelle.

    Ich habe es schon wieder vergessen, also könnte mir einer von euch mal erklären, was passieren sollte, wenn ich eine Datei mit 5 Bytes habe und 10 mal eine Methode "liesNächstesByte" aufrufe? Warum sollte in so einem Fall keine Exception ausgelöst werden? Vielleicht weil der Programmierer immer perfekt ist und solche offensichtlichen Fehler in der Realität garnicht vorkommen?! 😕



  • Ist jetzt sowieso nur noch bedingt ein Thema:

    Java API Dokumentation schrieb:

    This iterated read continues until one of the following conditions becomes true:

    The specified number of characters have been read,
    The read method of the underlying stream returns -1, indicating end-of-file, or
    The ready method of the underlying stream returns false, indicating that further input requests would block.



  • Hi,

    Optimizer schrieb:

    @Real: ja lol, du benutzt überall append(), wenn du da Strings hernimmst, müssen die erstmal in StringBuffer konvertiert werden.

    Nö, umgekehrt. xxx.toString();

    Du hast also nicht Strings mit StringBuffer verglichen. Wo ist denn jetzt genau das Problem, mehrere Strings nacheinander auszugeben?
    Und wenn du sie unbedingt konkatenieren willst, dann mach das alles in einer Anweisung mit '+', dann legt die VM gleich einen großen StringBuffer an und haut blitzschnell alles rein.

    ich habe StringBuffer dort implementiert, wo ich es für effizient hielt.
    Einen Vergleich mit String? Den habe ich! Ich habe einfach StringBuffer mit String ersetzt, alles schön mit "+" angehängt und es war langsam wie die Sau als ich die oben genannten Werte eingab.

    Liebe Grüße
    Real



  • Real schrieb:

    Einen Vergleich mit String? Den habe ich! Ich habe einfach StringBuffer mit String ersetzt, alles schön mit "+" angehängt und es war langsam wie die Sau als ich die oben genannten Werte eingab.

    Liebe Grüße
    Real

    Nein, du hast keinen Vergleich, weil '+' über StringBuffer realisiert wird, ich bereits sagte:

    Java API Dokumentation schrieb:

    String buffers are used by the compiler to implement the binary string concatenation operator +. For example, the code:

    x = "a" + 4 + "c"
    is compiled to the equivalent of:

    x = new StringBuffer().append("a").append(4).append("c")
    .toString()

    Es ist also reine Geschmacksache, ob man wie du schreibt:

    kapitalAusgabe= kapitalAusgabe.append(i).append(". Jahr: ").append(preis).append(" € \n");
    

    Oder wie ich schreibt:

    kapitalAusgabe  +=  i + ". Jahr: " + preis + " € \n";
    

    Dein ganzer H4ck (ich bezeichne es mal unfreundlicherweise so) ist in dem Glauben enstanden, dass du dann mehr Performance hast. Aber die Leute, die Java entwickeln, sind doch auch nicht blöd.

    daten.write(kapitalAusgabe.toString());
        daten.newLine();
        daten.write("________________________");
        daten.newLine();
    

    Hältst du das auch für effizienter als

    daten.write(kapitalAusgabe + "\n______\n"    // toString() wird implizit aufgerufen
    

    ?

    Wie du siehst, ist es eh vollkommen gleich, was du machst. Und wenn es z.B. um Zuweisungen (kopieren!) geht, dann kann ein immutable String punkten, wegen der von mir genannten Gründe. 🙂
    Dann noch frohes optimizern... 😉



  • Hi,
    wir sprechen hier aber immernoch von Java?!

    "HauptFenster.java": Fehler #: 354 : Inkompatible Typen; java.lang.String wurde gefunden, java.lang.StringBuffer ist erforderlich in Zeile 211, Spalte 24

    Zudem schreiben es auch alle Java-Bücher so.

    Auszug aus javabuch.de Kapitel 49 Performance-Tuning

    001 String s;
    002 s = "";
    003 for (int i = 0; i < 20000; ++i) {
    004   s += "x";
    005 }
    

    Das Programmfragment hat die Aufgabe, einen String zu erstellen, der aus 20000 aneinandergereihten "x" besteht. Das ist zwar nicht sehr praxisnah, illustriert aber die häufig vorkommende Verwendung des +=-Operators auf Strings. Der obige Code ist sehr ineffizient, denn er läuft langsam und belastet das Laufzeitsystem durch 60000 temporäre Objekte, die alloziert und vom Garbage Collector wieder freigegeben werden müssen. Der Compiler übersetzt das Programmfragment etwa so:

    001 String s;
    002 s = "";
    003 for (int i = 0; i < 20000; ++i) {
    004   s = new StringBuffer(s).append("x").toString();
    005 }
    

    Dieser Code ist in mehrfacher Hinsicht unglücklich. Pro Schleifendurchlauf wird ein temporäres StringBuffer-Objekt alloziert und mit dem zuvor erzeugten String initialisiert. Der Konstruktor von StringBuffer erzeugt ein internes Array (also eine weitere Objektinstanz), um die Zeichenkette zu speichern. Immerhin ist dieses Array 16 Byte größer als eigentlich erforderlich, so daß der nachfolgende Aufruf von append das Array nicht neu allozieren und die Zeichen umkopieren muß. Schließlich wird durch den Aufruf von toString ein neues String-Objekt erzeugt und s zugewiesen. Auf diese Weise werden pro Schleifendurchlauf drei temporäre Objekte erzeugt, und der Code ist durch das wiederholte Kopieren der Zeichen im Konstruktor von StringBuffer sehr ineffizient.

    Eine eminente Verbesserung ergibt sich, wenn die Klasse StringBuffer und ihre Methode append direkt verwendet werden:

    001 String s;
    002 StringBuffer sb = new StringBuffer(1000);
    003 for (int i = 0; i < 20000; ++i) {
    004   sb.append("x");
    005 }
    006 s = sb.toString();
    

    Hier wird zunächst ein StringBuffer erzeugt und mit einem 1000 Zeichen großen Puffer versehen. Da die StringBuffer-Klasse sich die Länge der gespeicherten Zeichenkette merkt, kann der Aufruf append("x") meist in konstanter Laufzeit erfolgen. Dabei ist ein Umkopieren nur dann erforderlich, wenn der interne Puffer nicht mehr genügend Platz bietet, um die an append übergebenen Daten zu übernehmen. In diesem Fall wird ein größeres Array alloziert und der Inhalt des bisherigen Puffers umkopiert. In der Summe ist die letzte Version etwa um den Faktor 10 schneller als die ersten beiden und erzeugt 60000 temporäre Objekte weniger.

    Ich gab dir sogar mein Wort, dass ich es getestet habe, sogar den Quellcode den du selbst testen konntest und du glaubst mir nicht. 😛

    Liebe Grüße
    Real



  • Hallo alle zusammen

    also ich habe gelesen und gelesen und habe hier immer noch keine antwort gefunden 🙂
    mich würde auch interessieren womit ich anfangen soll C oder C++? was mich interessiert ist auch Linux, Netzwerk programmierung und Spiele Entwicklung.

    was ist denn dafür besser? C oder C++?
    was C/C++ angeht bin ich noch ein totaler anfänger und stehe vor der entscheidung womit ich anfangen soll. habe aber auch schon 2 jahre erfahrung in delphi (ich weiß ich weiß bin ein überläufer 🙂 ) also ein totaler anfänger bin ich nicht.

    mfg SIDEX



  • Hi SIDEX,

    SIDEX schrieb:

    Hallo alle zusammen

    also ich habe gelesen und gelesen und habe hier immer noch keine antwort gefunden 🙂
    mich würde auch interessieren womit ich anfangen soll C oder C++? was mich interessiert ist auch Linux, Netzwerk programmierung und Spiele Entwicklung.

    was ist denn dafür besser? C oder C++?
    was C/C++ angeht bin ich noch ein totaler anfänger und stehe vor der entscheidung womit ich anfangen soll. habe aber auch schon 2 jahre erfahrung in delphi (ich weiß ich weiß bin ein überläufer 🙂 ) also ein totaler anfänger bin ich nicht.

    wenn du bei Linux Systemprogrammierung betreiben willst, dann ist ganz klar C angesagt, da Linux und die meisten Programme in C geschrieben sind.
    Man kann sicher nichts falsch machen, wenn man mit C anfängt und sich später evtl. C++ anschaut und beide Vorteile kombiniert.

    Liebe Grüße
    Reality



  • Real schrieb:

    Man kann sicher nichts falsch machen, wenn man mit C anfängt und sich später evtl. C++ anschaut und beide Vorteile kombiniert.

    Es gibt ja Leute in diesem Forum, die der Meinung sind, dass diese Reihenfolge den Stil versaut. Wenn man in dieser Reihenfolge lernt, dann wird es für den Lernenden schwer, in C++ nicht so wie in C zu programmieren. Das sollte man aber eigentlich gerade nicht tun. Wenn man es macht, sollte man lieber ganz auf C++ verzichten.

    Insgesamt geht der Trend eher zu Sprachen, die stärker von der darunterliegenden Maschine abstrahieren. In Zukunft wird sicherlich immer weniger C benötigt werden.



  • @REAL: Man sollte aber die Programmierung nicht an _einer_ Sprache ausmachen! Ich habe von COBOL über SCHEME, c/c++ bis hin zu Java und VB schon mal alles im Einsatz gehabt(haben müssen 😉 ).

    Du solltest Dir immer erst Dein Problem genau anschauen und danach die dafür geeigneteste Sprache auswählen! In Deinem jetzigem Fall wäre es c/c++.

    Gregor schrieb:

    Insgesamt geht der Trend eher zu Sprachen, die stärker von der darunterliegenden Maschine abstrahieren. In Zukunft wird sicherlich immer weniger C benötigt werden.

    ACK

    Grüssle



  • Hallo Gregor,
    das dürfte für uns kein Problem sein, da wir uns bei den schon mit OOP beschäftigt haben- er mit Delphi und ich mit Java (was ja C++ sehr ähnlich ist von der Syntax).
    Und meine Java-Kenntnisse werde ich auch nicht gehen lassen, da
    1. ich einen Vergleich haben und Erfahrung sammeln will
    2. das mein zukünftiger Beruf vielleicht vorraussetzt
    3. ich das in der Schule lerne.

    @Mr. White:
    Was heist ACK?

    Liebe Grüße
    Real


Anmelden zum Antworten