Könnten fstreams schneller als FILE * sein?



  • c++-ist-klasse schrieb:

    Es gibt viele Implementierungen sowohl von iostream als auch FILE*.

    Yepp, aber es ist nicht so, als ob die MS Implentierung die FILE * wegblasen würde, genausowenig tut es die gcc Implementierung.

    Mag sein, daß Du eine Implementierung, die suboptimal ist.

    Ich sah noch keine optimale.

    Es gibt aber keinen Grund, warum fstream schneller oder langsamer als FILE* sein soll.

    fstream prüft z.B. auf Buffer Overflows, FILE tut's nicht.



  • net schrieb:

    naja, wenn so'n fstream selber intern FILE* benutzt dann eher nicht.

    Diese Situation ist wohl akademischer Natur.

    aber wenn's irgendwelche mega-optimierten funktionen des OS benutzt, dann ist es bestimmt schneller als die C-'file' functions, die's eventuell nicht machen...

    Ohje. Du hast wirklich gar keine Ahnung wie Ein/Ausgabe funktioniert? Was ein Systemaufruf kostet? Bist du derselbe net, den ich immer für halbwegs kompetent in Lowlevel-Sachen eingeschätzt hatte?

    GPC: Die Frage trägt doch die Antwort schon in sich. Wäre der Geschwindigkeitsvorteil praktisch nicht umsetzbar, wäre er auch theoretisch nicht vorhanden. 😉
    Ich weiß nicht, woran es da scheitern könnte: Die Pendants zu den getc/putc-Makros sind inline-Funktionen (get/put und dann die entsprechenden streambuf-Methoden, deren Namen mir grade nicht einfallen). Nur overflow und underflow sind virtuelle Methoden. Ansonsten ist stdio und iostream nur Zeichen-in-Array-schreiben auf gehobenem Niveau. Es gibt da noch ein paar komische Sachen mit widen und narrow, die aber eigentlich auch wegoptimiert werden könnten. Sagen wir mal so: Ich hab aber keine Ahnung von den tieferen Details und zweifle mal vorsichtshalber die Prämisse des ganzen an: SIND sie denn wirklich langsamer? Auch bei einem optimierenden Compiler?



  • fstream und FILE werden doch sicherlich auf die natoiven File-APIs zugreifen. Wie sollte das denn sonst auch gemacht werden? Wenn man nicht auf die nativen File-APIs zugreift, müssten die C/C++-Libs ja eine eigene NTFS+FAT-Implementierung haben. Ehm, die Wahrscheinlichkeit dürfte wohl gegen Null gehen?!

    Also halten wir doch erstmal fest: FILE und fstream greifen auf die nativen APIs zu.

    So, aber das Konzept von fstream unf FILE ist doch anders? Also in einem anderen Level. Z.B. kann ich mir vorstellen, das wenn ich per Ausgabe-Operator (<<) was in einen fstream schiebe, das das gepuffert wird. Und erst bei einem flush oder wenn der Puffer eine bestimmte Grenze erreicht hat, der Puffer per nativer API reingeschoben wird.

    Bei FILE kann ich mir vorstellen, das es keinen Puffer gibt, das was ich schreibe, landet sofort beim nativen API.

    Naja, jedenfalls auf dem Level kann ich mir Performance-Unterschiede vorstellen.



  • Bashar schrieb:

    aber wenn's irgendwelche mega-optimierten funktionen des OS benutzt, dann ist es bestimmt schneller als die C-'file' functions, die's eventuell nicht machen...

    Ohje. Du hast wirklich gar keine Ahnung wie Ein/Ausgabe funktioniert?

    wieso? was findeste so verkehrt an dem satz?

    Bashar schrieb:

    Bist du derselbe net, den ich immer für halbwegs kompetent in Lowlevel-Sachen eingeschätzt hatte?

    hey, hat da jemand meinen account gehackt 😉



  • Bashar schrieb:

    GPC: Die Frage trägt doch die Antwort schon in sich. Wäre der Geschwindigkeitsvorteil praktisch nicht umsetzbar, wäre er auch theoretisch nicht vorhanden. 😉

    Ist ein Argument ^^
    Aber du weißt ja, in der Informatik ist theoretisch vieles möglich, nur praktisch noch nicht 😃

    Sagen wir mal so: Ich hab aber keine Ahnung von den tieferen Details und zweifle mal vorsichtshalber die Prämisse des ganzen an: SIND sie denn wirklich langsamer? Auch bei einem optimierenden Compiler?

    Ich kann natürlich nicht für jeden Fall sprechen, aber erst kürzlich gab's wieder einen Thread dazu ( ab Seite 2 bzw. 3 wird's interessant) und ich machte die Erfahrung auch schon selber. Ich komme nur gerade darauf, weil ich mit Xin darüber diskutiert habe, dem das auch so geht, dass die FILE* schneller sind.

    Wäre es auch möglich, dass die Verwendung von std::string einen (deutlichen) Performanceunterschied mit sich bringt? Ich denke eher nicht, jedenfalls nicht, wenn man sich nicht ungeschickt anstellt.



  • Artchi schrieb:

    Bei FILE kann ich mir vorstellen, das es keinen Puffer gibt, das was ich schreibe, landet sofort beim nativen API.

    stdio ist natürlich auch gepuffert. Da das OS selbst nochmal puffert und die meisten IO-Geräte (Platten) auch nochmal liegt der Grund hauptsächlich in der Vermeidung unzähliger überflüssiger Systemaufrufe. Die Existenzberechtigung von stdio ist von einem bestimmten Standpunkt aus gesehen in erster Linie die Bereitstellung von gepufferter Ein/Ausgabe. Das ganze noch in ein hübsches Interface gepackt, dazu noch formatierte Ein/Ausgabe ala printf/scanf und fertig.

    iostream ist im Grunde das gleiche, nur zum einen objektorientiert, und zum anderen liegt die Implementierung offener, da man die Streams von den Puffern getrennt hat, und jederzeit einem Stream einen anderen, auch selbstgeschriebenen, Puffer unterschieben kann, was bei der stdio nicht geht. Der OS-Anteil liegt dabei nur an dem, was passiert, wenn der Puffer voll (Ausgabe) bzw. leer (Eingabe) ist. Es gibt aber auch hier keinen Grund, warum bei stdio was anderes passieren sollte als bei iostream.



  • Bashar schrieb:

    Der OS-Anteil liegt dabei nur an dem, was passiert, wenn der Puffer voll (Ausgabe) bzw. leer (Eingabe) ist. Es gibt aber auch hier keinen Grund, warum bei stdio was anderes passieren sollte als bei iostream.

    bei windoze z.b. gibt's mehr als nur eine systemfunktion, um was auf'n datenträger zu bringen. zudem kannste bei WriteFile etc. noch 'ne menge options mitgeben. ein popeliges flag, welches z.b. eine 'fstream'-implementation beim aufruf so'ner systemfunktion anders setzt als die 'FILE*' funktionen das machen... und schon ist einer schneller als der andere...



  • fstream muss oft andere Dinge tun als FILE*, die auch z.T. threadsafe zu passieren haben, z.B. der Zugriff die globale locale. Das bremst. Enorm. Davon abgesehen begreife ich nicht was die Leute so an den iostreams fasziniert, das Interface ist doch der komplette Schrott.



  • hustbaer schrieb:

    Davon abgesehen begreife ich nicht was die Leute so an den iostreams fasziniert, das Interface ist doch der komplette Schrott.

    die finden eben die überladenen shift-operatoren so toll 😉



  • Manche schätzen auch die Tatsache, dass die Typen zur Compile-Zeit feststehen und daher kein Zwang besteht, diese zur Laufzeit aus einem Formatstring "herauszupopeln".



  • hustbaer schrieb:

    Davon abgesehen begreife ich nicht was die Leute so an den iostreams fasziniert, das Interface ist doch der komplette Schrott.

    Klar ist es etwas gewöhnungsbedürftig (gerade), aber immer noch deutlich besser (und sicherer) als das printf()/scanf()-Gebastel.



  • hustbaer schrieb:

    Davon abgesehen begreife ich nicht was die Leute so an den iostreams fasziniert, das Interface ist doch der komplette Schrott.

    Hallo Hustbaer,

    könntest Du das bitte begründen. Was genau am iostream-Interface ist warum Schrott?
    Ich wäre dankbar für eine konstruktive Antwort.

    Gruß
    Werner



  • net schrieb:

    bei windoze z.b. gibt's mehr als nur eine systemfunktion, um was auf'n datenträger zu bringen. zudem kannste bei WriteFile etc. noch 'ne menge options mitgeben. ein popeliges flag, welches z.b. eine 'fstream'-implementation beim aufruf so'ner systemfunktion anders setzt als die 'FILE*' funktionen das machen... und schon ist einer schneller als der andere...

    Das wär dann aber eher ein zufälliger Performance-Unterschied. Inwiefern hängt denn die Wahl der Systemfunktion davon ab, ob grad ein streambuf oder ein _filebuf geflusht werden soll?

    BTW mal an die letzte Entwicklung, die dieser Thread genommen hat:
    Das Interface für die formatierte Ein/Ausgabe ist ja gut und schön, aber auch nicht wirklich zwischen stdio und iostream vergleichbar. Ich hatte den Thread so verstanden, dass die Performance unterschiedlich ist, wenn man unformatiert, also zeichen- oder zeilenweise arbeitet.



  • Bashar schrieb:

    Ich hatte den Thread so verstanden, dass die Performance unterschiedlich ist, wenn man unformatiert, also zeichen- oder zeilenweise arbeitet.

    Ja, so hatte ich das auch gemeint. Interface ist mir in dem Punkt völlig egal.



  • Werner Salomon schrieb:

    könntest Du das bitte begründen. Was genau am iostream-Interface ist warum Schrott?
    Ich wäre dankbar für eine konstruktive Antwort.

    eventuell open/close. eventuell überhaupt die möglichkeit kaputter streams. vielleicht zu viel formatierungszeugs. eventuell ein komischer eingabeoperator, der verlangt, daß man vorher ein eigenes kaputtes objekt anlegt.



  • @volkard
    Wenn ich mich recht erinnere, warst du doch auch immer der Meinung, fstreams könnten schneller sein, oder nicht? Dir fallen doch bestimmt auch ein paar Sätze dazu ein...



  • Was den fstreams im Textmodus noch fehlt, ist die Rechtschreibprüfung in Hochgeschwindigkeit! 😃



  • könntest Du das bitte begründen. Was genau am iostream-Interface ist warum Schrott?

    Ein basic_streambuf Objekt hat eine locale - das macht keinen Sinn, zuunterst sollte etwas stehen was rein raw-io macht und nix von locales weiss -> sinnlose dependancy. Überhaupt ist das ganze basic_streambuf Interface IMHO unsauber, Input und Output schon auf unterster Ebene vermischt, weiter oben werden dann aber reine Input und reine Output Streams angeboten, huh? Die in und out Streams sind weitestgehend getrennt (z.B. unabhängig positionierbar), trotzdem pappt man as in ein Interface zusammen. Dann die Vermischung von Buffering und IO auf unterster Ebene - macht auch wenig Sinn.

    Dann die vermischung von "streams" (z.B. Sockets, Drucker, ...) und "random access IO" (Files, Memory-Buffer, ...), und wie schon erwähnt die Vermischung von Input-Only, Output-Only und Input/Output "streams" (bzw. "files"). Für soetwas sollte es getrennte Interfaces geben, und dann eben passende Adapter mittels denen ich aus einem "file" einen "stream" machen kann oder was auch immer.

    Also kurz: Die Trennung von IO, Buffering und "Formating" ist IMHO ungenügend, unsauber und unübersichtlich. Oder was volkard schon angesprochen hat, die ganzen State-Bits. Wieso gibts nicht eine Exception wenn ich was lesen will was nichtmehr da ist?

    Und dann die ganzen Namen OMG. "stossc", ja klar, versteht jeder auf Anhieb.

    ----

    Mit iostreams zu Arbeiten verbietet sich für mich in allen Fällen wo ich mehr machen muss/will als einfach bloss ein paar Strings/Zeichen in ein File zu schreiben bzw. zu lesen. Bevor ich mich tagelang mit iostreams rumärgere bei dem Versuch nen Socket, ein Stück NVRAM oder eine Serielle Schnittstelle mit streams zusammenzuknoten gehe ich lieber her und definiere meine eigene kleine Klassenhierarchie.



  • Oder was volkard schon angesprochen hat, die ganzen State-Bits. Wieso gibts nicht eine Exception wenn ich was lesen will was nichtmehr da ist?

    Also Exceptions gibts ja in der stream lib, die mußt du aber dummerweise vorher einmal explizit einschalten, dann bekommst du deine Exceptions. Ist aus Kompatibilitätsgründen leider so, das die Statebits standardmäßig herhalten. Aber es gibt Exceptions.

    gehe ich lieber her und definiere meine eigene kleine Klassenhierarchie.

    Verbietet dir ja auch keiner. Aber vielleicht hilft das hier ja auch etwas:
    http://www.boost.org/libs/iostreams/doc/index.html



  • hustbaer schrieb:

    Also kurz: Die Trennung von IO, Buffering und "Formating" ist IMHO ungenügend, unsauber und unübersichtlich.

    👍


Anmelden zum Antworten