c funktionen in c++ klassen benutzen?



  • hm ok....

    hat irgendwer tips, wo ich im inet gute infos zu dem thema file i/o usw bekomme ?



  • Schau dir mal die Headerdatei <fstream> und deren Klassen und Operationen an.
    Stichwort ist bei C++: "Streaming"





  • Badestrand schrieb:

    Schlechter Stil, aber wenn dann gibts eher leichte Geschwindigkeits-Vorteile für die C-Funktionen (soweit ich weiß).

    Das hängt davon ab, wofür die Dateistreams benutzt werden. std::fstream per se einen besseren Stil als den C-Dateifunktionen zu attestieren halte ich für unangebracht; dadurch, daß man das Objekt vor den .-Operator schreibt und nicht als Parameter übergibt, wird das ganze nicht besser.

    Ein Vorteil der C++-Streams ist, daß das Streamen von PODs und überladenen Typen wesentlich einfacher und fehlerunanfälliger ist. Je nach Anwendungsfall (z.B. wenn man hauptsächlich fstream::write() und fstream::read() benutzt) können aber die C-Funktionen auch qualitativ gleichwertig sein, und da sie in allen mir bekannten Implementationen ein wenig bis sehr viel schneller sind, bevorzuge ich sie gewöhnlich.



  • audacia schrieb:

    Badestrand schrieb:

    Schlechter Stil, aber wenn dann gibts eher leichte Geschwindigkeits-Vorteile für die C-Funktionen (soweit ich weiß).

    Das hängt davon ab, wofür die Dateistreams benutzt werden. std::fstream per se einen besseren Stil als den C-Dateifunktionen zu attestieren halte ich für unangebracht

    Es ist aber korrekt. Und zwar allein dadurch, dass man nur mit diesen Kapselungen Thread-sicher programmieren kann. C-Dateiströme sind rohe Ressourcenhandles, hier korrektes Verhalten garantieren zu wollen ist quasi aussichtslos. Das heißt, dass man diese Stream-Handles in allen kritischen Bereichen kapseln *muss*. Und dann kann man auch gleich die bereits existierenden Varianten verwenden.



  • ich will jetzt nicht provozieren, dass der thread schon wieder in die ecke abrutscht, aber: ansi-c funktionen zu verwenden, weil sie angeblich schneller seien, gehört in die ecke der microoptimierungen. bevor man sich über sowas gedanken macht, sollte man lieber die "sicheren" c++ varianten verwenden.

    wenn man dann irgendwann feststellt, dass man doch noch ein wenig mehr performance rauskitzeln muss, kann man sich nochmal die "alten" methoden angucken.



  • na dann werde ich mich auch mal in die iostream einlesen.

    bei mir ists nur so, dass ich schon 3 jahre lange c benutze und vor ca einem jahr begonnen habe auch c++ zu verwenden vor allen wegen dem oop paradigma 😉



  • @Konrad Rudolph: ist std::fstream threadsicher?
    Bezogen auf Exceptionsicherheit stimme ich dir aber zu (allerdings verwende ich für diesen Fall ohnehin ein kleines Handle-Wrapper-Template, das auch bei WinAPI-Handles recht nützlich ist).

    thordk schrieb:

    ansi-c funktionen zu verwenden, weil sie angeblich schneller seien, gehört in die ecke der microoptimierungen.

    Das dachte ich auch, bis ich feststellte, das die C-Streams in manchen Situationen bis zu 4x schneller sind. Und das ist keine "premature optimisation" oder Mikrooptimierung mehr, das ist die Folge des fragwürdigen Designs von Teilen der C++-Standard-Library.

    Dennoch ist es für Einsteiger wohl sinnvoller, die C++-Streams zu verwenden, schon wegen der Exceptionsicherheit und der Tatsache, daß man fstream.close() geruhsam vergessen kann 🙂



  • faktor 4? klingt unglaubwürdig 😃 welche randbedingungen herrschten da vor?



  • thordk schrieb:

    faktor 4? klingt unglaubwürdig 😃

    Der Faktor 4 ergab sich bei detaillierteren Nachmessungen. In der Praxis liegt er eher noch höher.

    thordk schrieb:

    welche randbedingungen herrschten da vor?

    Dinkumware STL v5.01, C++Builder 2007, folgende Funktion:

    bool BinFile::load_internal (const std::string& filename) const
    {
        std::ifstream cppfile;
        std::FILE* cfile;
        size_t s;
    
        s = getFileSize (filename);
        _data.resize (s);
    
        if (Variante 1)
        {
            cfile = std::fopen (filename.c_str (), "rb");
            if (!cfile)
                return false;
            std::fread (&_data[0], 1, s, cfile);
            std::fclose (cfile);
        }
        else // Variante 2 - mindestens 4x langsamer
        {
            cppfile.open (filename.c_str (), std::ios_base::binary | std::ios_base::in);
            if (!cppfile.good ())
                return false;
            cppfile.read (&_data[0], s);
            cppfile.close ();
        }
    
        return true;
    }
    

    Der Grund ist vermutlich, daß Dinkumware sich bei der Implementation von ifstream::read() den copy()-Algorithmus zum Kopieren von Daten aus dem Dateipuffer zum Ziel verwendet. Und der ist nunmal für nicht sonderlich effizient.



  • Zur Threadsicherheit von std::fstream, die kann eigentlich nicht gegeben sein, da der Standard gar keine Threads kennt.



  • Threadsicher sind an sich weder die fstreams noch die FILE-Handles. Zum Faktor 4: Das ist peinlich, aber leider wohl richtig. Na ja; wieso implementiert die nichtmal jemand richtig? fstreams könnten konzeptuell *schneller* sein als C-Streams. Abgesehen davon *ist* Faktor 4 eine absolute Mikrooptimierung, vor allem im Bereich I/O, das ist nämlich selten der Bottleneck.

    … aber abgesehen davon ist das natürlich trotzdem eine legitime Optimierung, wenn Profiling ergeben hat, dass hier beschleunigt werden kann.



  • audacia schrieb:

    @Konrad Rudolph: ist std::fstream threadsicher?...

    Tyrdal schrieb:

    Zur Threadsicherheit von std::fstream, ...

    Hat auch niemand behauptet.
    Niemand hat behauptet, dass jede Implementierung vom fstream threadsafe wäre...
    Sondern nur:

    Konrad Rudolph schrieb:

    ...dass man nur mit diesen Kapselungen Thread-sicher programmieren kann. ...

    Das bedeutet: Wenn ich Streams nutze, kann ich (z.B. hinter dieser Kapsel) threadsafe programmieren. Mit einem direkten FILE* geht das eben nicht ...

    Gruß,

    Simon2.



  • d3f3nd3r schrieb:

    na dann werde ich mich auch mal in die iostream einlesen.

    bei mir ists nur so, dass ich schon 3 jahre lange c benutze und vor ca einem jahr begonnen habe auch c++ zu verwenden vor allen wegen dem oop paradigma 😉

    Wenn das OOP Paradigma einer deiner Gruende war, "auch" C++ zu verwenden, dann solltest du gerade deswegen erstmal den C++ streams Vorrang vor den C-I/O-Funktionen geben. Und dann evtl. das "auch" streichen und C++ schreiben und nicht wie so einige Buecher suggerieren C schreiben und da wo C nicht weiter kommt C++ Elemente zu verwenden, bzw. da wo die C++ Kenntnisse nicht ausreichen den Code mit C zusammenkleben.



  • pumuckl schrieb:

    ...wie so einige Buecher suggerieren C schreiben und ... da wo die C++ Kenntnisse nicht ausreichen den Code mit C zusammenkleben.

    Da sprichst Du ein großes Wort gelassen aus ! 👍

    Gruß,

    Simon2.



  • @Konrad Rudolph
    Es gibt durchaus Programme, die große Datenmengen lesen und schreiben müssen. Da sind die IO-Operation ein Bottleneck.
    Ich habe auch schon mal Vergleiche der Geschwindigkeiten verschiedener Stream-Implementationen gemacht und auch festgestellt, dass Dinkumware und RougeWave sehr langsam sind. STLPort jedoch liegt nahe bei den puren C-Funktionen.



  • Wenn man große Datenmengen am Stück in Dateien schreiben oder auslesen will, dann ist häufig die ungepufferte Variante schneller als die standardmäßig verwendete Pufferung.
    (Und dann sollte es kaum mehr einen Unterschied zwischen den C++ Streams und den C FILE-Funktionen geben)


Anmelden zum Antworten