Programmlaufzeitfrage



  • Ähm, also ein "sauberes" main sieht so aus:

    int main(int argc, char *argv[]) {
      //Code usw. 
      return 0;
    }
    

    Aber das ist nicht so wichtig. Sag mal, wie viele Zeilen hat die Datei? Denn dein Freund bricht bei 1000000 das Lesen ab, du nicht.
    Die Listings sind eh sehr verschieden, so holst du z.B. viel früher die Zeit für start als er.



  • also die Datei hat 160000 Zeilen, das mit der unterschiedlichen Startzeit ok, da hab ich dann nicht aufgepasst, aber alleine auch wenn man die Programme startet merkt man schon nen deutlichen Unterschied, also ist bei ihm wirklich bis zum ende weniger als 1 sekunde und bei mir mehr als 5 sekunden, das merkt man auch, das mit der zeit war dann nur um an genau daten zu kommen



  • Hi,

    ein gewisser Aspekt durfte "string" sein: Hier verwendest Du die sichere dynamische Speicherverwaltung, während der Kollege einfach fix 25 Byte reserviert und sich darauf verlässt, dass das passt.
    Diese Sicherheit "kostet" natürlich - bei der Erst-Initialisierung (sprich: "string text, muell;") ebenso, wie in der Leseschleife.

    Ich würde mal versuchen (wenn Du keinen Profiler zur Hand hast), die Zeitmessung direkt um die Schleife zu machen, damit Du auf jeden Fall schonmal die Initialisierungszeiten von string und fstream raus hast. Die können bei so kurzen Gesamtlaufzeiten schon ganz schön ins Gewicht fallen.

    Außerdem würde ich nochmal mit einer deutlich größeren Datei testen ...
    Nochmal die Frage: Hast Du die Optimierungen beim Compiler aktiviert ?

    Gruß,

    Simon2.



  • Hallo,

    der Zeitunterschied hängt höchstwahrscheinlich mit der Verwendung der iostreams zusammen. Letztlich ist das natürlich abhängig von der verwendeten Standardlib-Implementation, aber ich habe z.B. die Erfahrung gemacht, dass das Lesen aus einem fstream (Dinkumware-Lib) unter Windows doch deutlich langsamer als das Lesen aus einem FILE-Objekt ist.

    Was du noch machen solltest: füge am Anfang deines Programms noch ein

    std::ios_base::sync_with_stdio(false);
    

    ein. Dann müssen die C++ Ströme wenigstens nicht mehr mit den C-Strömen synchronisiert werden.

    Achso: die Code-Stücke sind natürlich keinesfalls äquivalent. Der C-Code ist so z.B. auf eine feste Länge der Eingabe beschränkt.



  • Hast Du die Optimierungen beim Compiler aktiviert ?

    Was meinst du damit?

    Ansonsten erstmal vielen Dank für eure Hilfe, werde mal probieren das noch etwas anzupassen um bei meinemProgramm auf bessere Laufzeiten zu bekommen.

    aber die Aussage das fstream langsamer ist als Datei pointer, ist ja genau das was ich auch festgestellt habe, in sofern danke für die bestätigung

    Habe nämlich mal irgendwo gelesen, das sie c++string genauso schnell ist wie die Ansi string
    und das wäre ja dann zum mindest in dem Beispiel wiederlegt, danke



  • neu Hier schrieb:

    Hast Du die Optimierungen beim Compiler aktiviert ?

    Was meinst du damit?
    ...

    Bei Deinem Compiler mal mit den Optionen "-o" rumspielen (vielleicht noch "Debug"-Flags abknipsen).

    neu Hier schrieb:

    ...
    Habe nämlich mal irgendwo gelesen, das sie c++string genauso schnell ist wie die Ansi string...

    Ich frage mich, wer das wohl geschrieben hat ? "ANSI-Strings" haben ja keine eigene Speicherverwaltung (OK, strtok() mal außen vor gelassen), sondern ueberlassen das ganz den Aufrufer. Wenn der um seine strcpy()/-cmp()/...-Funktionen ebenfalls eine dynamische Speicherverwaltung bauen würde, würde das vllt. stimmen. Das hat dann aber nichts mehr mit "ANSI" zu tun.

    Gruß,

    Simon2.



  • Habe nämlich mal irgendwo gelesen, das sie c++string genauso schnell ist wie die Ansi string

    wenn dein C Freund die strings in C genau so dynamisch allocieren wuerde, dann ja ...

    Programmiertechnisch vergleichst du aepfel mit birnen ...
    Praktisch gesehen ist der vergleich natuerlich schon zulaessig, machen ja beide programme das selbe.
    Problem ist nur dass das C programm auf datentechnische gegebenheiten spezialisiert ist (1000000 zeilen maximal, max 25 zeichen pro zeile) das ist schon ne heftige Sache.

    Noch was. std::string wird beim allokieren niemals mit nem statischen array
    char staticString[256];
    konkurieren koennen. dazu isses auch ned gedacht.
    sondern es ist ne vereinfachung fuer sowas :

    char * pDynString = (char *)malloc(len);
    // irgend was machen
    free(pDynString);

    wenn du unter c++ auch feste groessen hasst, hindert dich keiner dran statische arrays zu verwenden. Wenn du die oefter allokierst, solltest du das auch ...

    wenn ich fuer "deine Aufgabenstellung" nen konkurrierentes programm schreiben sollt, wuerden da keine std::strings auftauchen und auch streams sind da nicht wirklich optimal.
    Ich wuerde genau so mit festen puffern, und wahrscheinlich in speicherbereich gemappte dateien (BS speziefisch), oder mit den filepuffern direkt arbeiten ...

    Ciao ...



  • Mit iostreams wirst du *nie* so schnell werden wie mit den "stdio" Funktionen von C. Eigentlich eine uralte Geschichte, sollte jeder wissen. iostreams sind IMHO sowieso der mieseste unnötigste Teil der ganzen C++ Standard Library.



  • Noch mal zum Thema C++ schnell oder nicht. Folgendes Programm macht auch nicht weniger als das des OP, benötigt aber für die angegebenen Datei mit 160000 Zeilen bei ca 25 Zeichen pro Zeile weniger als 0,6sec - inklusive Schreiben der neuen Datei.
    (Generiert mit VC++2005 Express - Release-Mode)

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <iterator>
    #include <algorithm>
    #include <limits>
    
    struct DoppelZeile
    {
        friend std::istream& operator>>( std::istream& in, DoppelZeile& dz )
        {
            if( !getline( in, dz.m_zeile ).eof() )
                in.ignore( std::numeric_limits< std::streamsize >::max(), 
                    std::istream::traits_type::to_int_type( '\n' ) );
            return in;
        }
        friend std::ostream& operator<<( std::ostream& out, const DoppelZeile& dz )
        {
            return out << dz.m_zeile << std::endl;
        }
    private:
        std::string m_zeile;
    
    };
    
    int main()
    {
        using namespace std;
        ifstream in("input.txt");
        ofstream out("output.txt");
        copy( istream_iterator< DoppelZeile >( in ), istream_iterator< DoppelZeile >(),
            ostream_iterator< DoppelZeile >( out ) );
        return 0;
    }
    

    Wobei mir nicht ganz klar ist, ob jetzt jede gerade oder jede ungerade Zeile gelesen werden soll.

    Plotzenhotz schrieb:

    Mit iostreams wirst du *nie* so schnell werden wie mit den "stdio" Funktionen von C.

    dafür gibt es keinen technischen Grund. Vorausgesetzt man vergleicht gleiche Funktionalitäten, was hier nicht ganz einfach ist, wie wir ja schon gesehen haben.

    Ansonsten stimme ich mit HumeSikkins überein. Da hängt einiges von der Implementierung in der STL ab ... und auch von einer schnellen Platte 😉 .

    Gruß
    Werner



  • Dynamische Speicheranforderungen und eine überaus komplizierte (dafür natürlich auch mächtige) Library vs. keine dynamischen Speicheranforderungen und eine relativ einfache Library sind also kein technischer Grund?

    Mir auch egal, es bleibt die Tatsache dass auch mit MSVC 2005 (SP1 BETA) im Release Mode und natürlich mit 'Link Time Code Generation' an die iostreams Variante gegenüber der stdio Variante ganz gewaltig abstinkt. Probiers selbst wenn dus nicht glaubst:

    #define _WIN32_WINNT 0x0501
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <conio.h>
    #include <time.h>
    #include <windows.h>
    #include <mmsystem.h>
    #undef min
    #undef max
    #include <iostream> 
    #include <string> 
    #include <fstream> 
    #include <iterator> 
    #include <algorithm> 
    #include <limits> 
    
    #pragma comment(lib, "winmm")
    
    static const char* g_inputFileName = "c:\\in.txt";
    static const char* g_outputFileName = "c:\\out.txt";
    
    static const size_t gc_lineCount = 160*1000;
    
    void CreateTestFile()
    {
        FILE* outFile = fopen(g_inputFileName, "w");
        if(!outFile)
    		abort();
    
    	for(size_t i = 0; i < gc_lineCount; i++)
    	{
    		int r = rand() % 3;
    		char const* s = 0;
    		switch(r)
    		{
    		case 0: s = "Bla, Bloe\n"; break;
    		case 1: s = "Ding, Dong\n"; break;
    		case 2: s = "X, Y\n"; break;
    		}
    
    		fputs(s, outFile);
    	}
    
    	fclose(outFile);
    }
    
    void ReadInputFile()
    {
        FILE* inFile = fopen(g_inputFileName, "r");
        if(!inFile)
    		abort();
    
    	char buffer[1024];
    	while(fgets(buffer, sizeof(buffer), inFile))
    		;
    
    	fclose(inFile);
    }
    
    size_t TestStdio()
    {
        FILE* inFile = fopen(g_inputFileName, "r");
        if(!inFile)
    		abort();
    
        FILE* outFile = fopen(g_outputFileName, "w");
        if(!outFile)
    		abort();
    
    	size_t outLines = 0;
    
    	char buffer[1024];
    	while(1)
    	{
    		if(!fgets(buffer, sizeof(buffer), inFile))
    			break;
    		if(!fgets(buffer, sizeof(buffer), inFile))
    			break;
    
    		if(fputs(buffer, outFile) < 0)
    			abort();
    
    		outLines++;
    	}
    
    	fclose(inFile);
    	fclose(outFile);
    
    	return outLines;
    }
    
    struct DoppelZeile 
    { 
        friend std::istream& operator>>( std::istream& in, DoppelZeile& dz ) 
        { 
            in.ignore(std::numeric_limits<std::streamsize>::max(), std::istream::traits_type::to_int_type('\n')); 
            getline(in, dz.m_zeile);
            return in; 
        } 
        friend std::ostream& operator<<( std::ostream& out, const DoppelZeile& dz ) 
        { 
            return out << dz.m_zeile << std::endl; 
        } 
    private: 
        std::string m_zeile; 
    
    }; 
    
    size_t TestIostream1() 
    { 
    	std::ifstream in(g_inputFileName);
    	std::ofstream out(g_outputFileName);
    	std::copy(std::istream_iterator<DoppelZeile>(in), std::istream_iterator<DoppelZeile>(),
    		std::ostream_iterator<DoppelZeile>(out));
    	return 0;
    }
    
    size_t TestIostream2() 
    { 
    	std::ifstream in(g_inputFileName);
    	std::ofstream out(g_outputFileName);
    
    	std::string str;
    	str.reserve(1024);
    
    	size_t outLines = 0;
    
    	while(in.good())
    	{
    		in.ignore(std::numeric_limits<std::streamsize>::max(), std::istream::traits_type::to_int_type('\n'));
    		if(std::getline(in, str).eof())
    			break;
    		out << str << std::endl;
    		outLines++;
    	}
    
    	return outLines;
    }
    
    int main(int argc, char** argv)
    {
    	CreateTestFile();
    
    	if(::timeBeginPeriod(1) != TIMERR_NOERROR)
    		abort();
    
    	size_t outLineCount = 0;
    	DWORD t0, t1;
    
    	// TestStdio
    	for(unsigned rep = 0; rep < 5; rep++)
    	{
    		::DeleteFileA(g_outputFileName);
    		ReadInputFile();
    		ReadInputFile();
    		printf("TestStdio...\n");
    		t0 = ::timeGetTime();
    		outLineCount = TestStdio();
    		t1 = ::timeGetTime();
    		printf("Lines: %ld, time: %ld msec\n", long(outLineCount), long(t1 - t0));
    	}
    
    	// TestIostream1
    	for(unsigned rep = 0; rep < 5; rep++)
    	{
    		::DeleteFileA(g_outputFileName);
    		ReadInputFile();
    		ReadInputFile();
    		printf("TestIostream1...\n");
    		t0 = ::timeGetTime();
    		outLineCount = TestIostream1();
    		t1 = ::timeGetTime();
    		printf("Lines: %ld, time: %ld msec\n", long(outLineCount), long(t1 - t0));
    	}
    
    	// TestIostream2
    	for(unsigned rep = 0; rep < 5; rep++)
    	{
    		::DeleteFileA(g_outputFileName);
    		ReadInputFile();
    		ReadInputFile();
    		printf("TestIostream2...\n");
    		t0 = ::timeGetTime();
    		outLineCount = TestIostream2();
    		t1 = ::timeGetTime();
    		printf("Lines: %ld, time: %ld msec\n", long(outLineCount), long(t1 - t0));
    	}
    
    	::timeEndPeriod(1);
    
    	printf("\nPress any key to continue.\n");
    	getch();
    
    	return 0;
    }
    

    Ergebnis:

    TestStdio...
    Lines: 80000, time: 84 msec
    TestStdio...
    Lines: 80000, time: 108 msec
    TestStdio...
    Lines: 80000, time: 84 msec
    TestStdio...
    Lines: 80000, time: 83 msec
    TestStdio...
    Lines: 80000, time: 87 msec
    TestIostream1...
    Lines: 0, time: 702 msec
    TestIostream1...
    Lines: 0, time: 705 msec
    TestIostream1...
    Lines: 0, time: 692 msec
    TestIostream1...
    Lines: 0, time: 712 msec
    TestIostream1...
    Lines: 0, time: 717 msec
    TestIostream2...
    Lines: 80000, time: 701 msec
    TestIostream2...
    Lines: 80000, time: 690 msec
    TestIostream2...
    Lines: 80000, time: 693 msec
    TestIostream2...
    Lines: 80000, time: 692 msec
    TestIostream2...
    Lines: 80000, time: 707 msec
    
    Press any key to continue.
    

    Das ist Faktor 8 (jeweils schnellste Zeiten).

    p.S.: noch kürzere Zeilen zu verwenden (1 Zeichen/Zeile, und mit "str.reserve(1024);" auskommentiert) so dass die small-string Optimierung vom MSVC 2005 auch sicher greift macht im übrigen keinen Unterschied. Längere Zeilen (400~500 Zeichen) helfen sehr den Unterschied drastisch zu verkleinern, schneller bleibt trotzdem die stdio Variante.



  • Plotzenhotz schrieb:

    Dynamische Speicheranforderungen und eine überaus komplizierte (dafür natürlich auch mächtige) Library vs. keine dynamischen Speicheranforderungen und eine relativ einfache Library sind also kein technischer Grund?

    doch.
    und genau deswegen misst du mist.
    benutz doch mal <fstream> ohne <string>. das tut nämlich auch gehen.



  • @volkard: Na dann werd ich das wohl probieren. Wollen wir wetten dass iostream trotzdem langsamer bleibt als stdio?



  • p.S.: @volkard: ich wollte eigentlich auch nur die "0,6 Sekunden" von "Werner Salomon" etwas relativieren - er hat ja den Vergleich mit stdio nicht angestellt, diesen habe ich jetzt nachgeholt -- um zu zeigen dass seine 0,6 Sekunden bloss wenig klingen weil der OP anscheinend einen sehr langsamen PC hat 🙂



  • Plotzenhotz schrieb:

    Wollen wir wetten dass iostream trotzdem langsamer bleibt als stdio?

    Klar. Es handelt sich ja auch um eine extrem dynamische Bibliothek, die objektorientiert implementiert ist, mit dem gesamten damit verbundenen Overhead (virtuelle Funktionen).

    Als Resultat erhält man ein ungemein mächtiges und nützliches Werkzeug, das quasi beliebig erweitert werden kann. Das mit stdio zu vergleichen ist in jedem Fall unsinnig.



  • Meine Ergebnisse:
    Jeweils 100000 Zeilen a 25 Zeichen lesen und jede zweite Zeile in neue Datei schreiben.
    (VC++ 8.0 release-build Pentium 4)

    #include <iostream>
    #include <fstream> 
    #include <string> 
    #include <time.h> 
    #include <conio.h> 
    
    using namespace std; 
    
    int main () 
    {   // VARIANTE 1 C++
        clock_t start=0, finish=0; 
        string text,text2, muell; 
    
        start = clock();  
    
        ifstream indatei("c:\\EINLAUF.TXT");  
        ofstream outdatei("c:\\EINLAUFXXX.TXT"); 
    
        if(indatei) 
            while(getline(indatei, text2)) 
            { 
                    text += text2;
                    text += "\n";
                    getline(indatei,muell); 
            } 
    
        outdatei << text; 
    
        finish = clock();     
        indatei.close();
        outdatei.close();
        cout  << "VARIANTE 1 C++ " << endl
         << "Rechenzeit C++ -Code : " << (double)(finish - start) << " ms" << endl << endl; 
    
    //*****************************************************************        
    
    #define IN_DATEI "c:\\EINLAUF.TXT" 
    #define OUT_DATEI "c:\\EINLAUFXXX.TXT" 
    #define N 25            // Vektorlänge der Char-Felder 
    #define ABBR 1000000    // max. Schleifenlänge für Not-Abbruch 
    
        FILE *fptr1; 
        FILE *fptr2; 
        unsigned long is = 0; 
        char input[N], dummy[N]; 
        start=0, finish=0; 
    
        fptr1 = fopen(IN_DATEI, "r");    // Datei mit Werten 
        fptr2 = fopen(OUT_DATEI, "w");    // Ergebnisdatei mit halbierter Auflösung 
    
        if (!fptr1) 
            printf("Fehler beim Oeffnen der Input-Datei!\n"); 
        else 
        { 
            start = clock();    // 1. Wert für Rechenzeitbestimmung 
    
            while (fgets(dummy,    N, fptr1) != NULL)    // jedes Wertepaar mit ungeradem Index wird ignoriert 
            { 
                fgets(input, N, fptr1);    // jedes Wertepaar mit geradem Index wird gespeichert 
                fprintf(fptr2, "%s", input); 
                is++;    
                if (is>=ABBR) 
                    break;    // Notausstieg aus while-Schleife bei einer best. max. Zeilenzahl 
            } 
    
            finish = clock();    // 2. Wert für Rechenzeitbestimmung 
            _fcloseall();     
            printf ("VARIANTE 2 C-Code\n");
            printf("Anzahl der Wertepaare vorher: %lu\n", is*2); 
            printf("Anzahl der Wertepaare jetzt: %lu\n", is); 
            printf("Rechenzeit C-Code : %.0f ms\n\n", (double)(finish - start)); 
            //printf("CPS:  %f\n\n", (float)CLOCKS_PER_SEC); 
        } 
    //*******************************************************************************
    //Letzer Versuch C++
        start = clock();
        ofstream aus;
        aus.open("c:\\EINLAUFXXX.TXT", ios_base::out | ios_base::binary| ios_base::trunc);
        ifstream ein;
        ein.open("c:\\EINLAUF.TXT", ios_base::in | ios_base::binary| ios_base::ate);
        char* zBuf;
        int len = ein.tellg();
        if (zBuf = new char [len])
        {
          ein.seekg(ios::beg);
          ein.read(zBuf, len);
        }
        else return -1;
    
        char* p = zBuf, *p2, *p3;
        size_t a, s = 0;
        int i = 0;
        for (int toggle = 0 ; i < len; ++i)
        {
            if (zBuf[i] == 10)
            {
                toggle ^= 1;        
                if (toggle)
                {
                    p2 = &zBuf[i+1];         
                    continue;
                }
                else
                {
                    p3 = &zBuf[i+1];     
                    a = p3-p2;
                    memcpy(p, p2, a);
                    p += a, s += a;
                }
            }
        }
        if (zBuf[i] != 10)
        {
            p3 = &zBuf[i], a = p3-p2;
            memcpy(p, p2, a);
            p += a, s += a;
        }
        aus.write(zBuf, (streamsize)s);
    
        finish = clock();
        cout    << "VARIANTE 3 C++ ohne std::string" << endl
                << "Rechenzeit C/C++ Code : " << (double)(finish - start) << " ms" << endl << endl; 
        ein.close();
        aus.close();
        delete[] zBuf;
        return 0;
    }
    

    Ausgabe:

    VARIANTE 1 C++
    Rechenzeit C++ -Code : 203 ms

    VARIANTE 2 C-Code
    Anzahl der Wertepaare vorher: 100000
    Anzahl der Wertepaare jetzt: 50000
    Rechenzeit C-Code : 109 ms

    VARIANTE 3 C++ ohne std::string
    Rechenzeit C/C++ Code : 31 ms



  • So. Ich hab den Test mit "in.getline(buffer, sizeof(buffer))" gemacht (also ganz ohne std::string - womit wir nun endlich genau die selbe Funktionalität verglichen hätten), der ist nun statt Faktor 8.3 etwa Faktor 7.5 langsamer.

    BTW: dass die "ios_base::binary und alles auf einmal lesen" Variante schnell ist ist klar, die verwendet ja auch die iostreams Library für nix anderes als einen grossen Block Daten zu kopieren. Das bringt man mit stdio genauso hin, und sicher auch wieder schneller, wenn auch wahrscheinlich bloss um ein paar Takte.

    @Konrad Rudolph: ich hab auch von Anfang an behauptet dass iostreams langsamer sein wird als stdio (lies ein paar Postings weiter oben). Bloss kam dann so ein "dafür gibt es garkeinen Grund" Kommentar. Ob es einen Grund gibt hin oder her, auf jeden Fall ist es so, und ich sah mich genötigt das zu demonstrieren.



  • Plotzenhotz schrieb:

    So. Ich hab den Test mit "in.getline(buffer, sizeof(buffer))" gemacht (also ganz ohne std::string - womit wir nun endlich genau die selbe Funktionalität verglichen hätten), der ist nun statt Faktor 8.3 etwa Faktor 7.5 langsamer.

    das ist immernoch unfug.
    zeig mal dein endgültiges programm, das unter fairen bedingungen <cstdio> mit <fstream> vergleicht und faktor 7.5 schneller ist. ich gebe mir ausnahmsweise die mühe, es zu verreißen, da du mir in anderen threads deutlich als ahnunghaber und hilfsbereiter aufgefallen bist.



  • Das ganze vergleichen hier ist doch Bullshit Leute !
    Und auch noch Faktoren rausgeben wollen, was die clib schneller ist wie eine IOStream impl?

    Jeder der mit streams arbeitet, weiss das er es ned wegen der geschwindigkeit tut. Wenn man sagt das c++ performant sein kann/soll, meint man in c++ auch so programmieren kann, das die geringfuegig geringere performance kein Grund sein soll die anderen vorteile von c++, der stl und dem stream konzept ueber boartd zu werfen !

    Und wenn ich wirklich auf speed aus bin bei dateioperationen ( Bitte welchem vernunftigen Programmierer intressiert nen minimaler performanceverlust bei dateioperationen auf nem multhithreading/multiprocessing BS ??? ) aus bin, werd ich doch zuerst mein BS konsultieren (Posix, winapi) und die streams / filebuffer bei seite legen ...

    Ciao ...



  • ich lass jetzt mal das hier dorchlaufen:

    #include <iostream>
    #include <cstdio>
    #include <fstream>
    #include <string>
    using namespace std;
    
    #define g_inputFileName "test.txt"
    #define gc_lineCount 100000000
    
    void CreateTestFile()
    {
        FILE* outFile = fopen(g_inputFileName, "w");
        if(!outFile)
            abort();
    
        for(size_t i = 0; i < gc_lineCount; i++)
        {
            int r = rand() % 3;
            char const* s = 0;
            switch(r)
            {
            case 0: s = "Bla, Bloe\n"; break;
            case 1: s = "Ding, Dong\n"; break;
            case 2: s = "X, Y\n"; break;
            }
    
            fputs(s, outFile);
        }
    
        fclose(outFile);
    }
    
    int countLineNumbers1(){
    	int result=0;
    	FILE* inFile = fopen(g_inputFileName, "r");
    	if(!inFile)
    		abort();
    	char buffer[1024];
    	while(fgets(buffer, sizeof(buffer), inFile))
    		++result;
    	fclose(inFile);
    	return result;
    }
    
    int countLineNumbers2(){
    	int result=0;
    	ifstream inFile(g_inputFileName);//edit: hier war fehlerhaft ios::binary
    	if(!inFile)
    		throw 4711;
    	char buffer[1024];
    	while(inFile.getline(buffer,1024))
    		++result;
    	return result;
    }
    
    int countLineNumbers3(){
    	int result=0;
    	ifstream inFile(g_inputFileName,ios::binary);
    	if(!inFile)
    		throw 4711;
    	string buffer;
    	while(getline(inFile,buffer))
    		++result;
    	return result;
    }
    
    int main()
    {
    	CreateTestFile();
    	for(int i=0;i<10;++i)
    	{
    		{
    			clock_t start=clock();
    			cout<<1<<' '<<countLineNumbers1()<<' ';
    			cout<<(clock()-start)/double(CLOCKS_PER_SEC)<<endl;
    		}
    		{
    			clock_t start=clock();
    			cout<<2<<' '<<countLineNumbers2()<<' ';
    			cout<<(clock()-start)/double(CLOCKS_PER_SEC)<<endl;
    		}
    		{
    			clock_t start=clock();
    			cout<<3<<' '<<countLineNumbers3()<<' ';
    			cout<<(clock()-start)/double(CLOCKS_PER_SEC)<<endl;
    		}
    	}
    	return 0;
    }
    

    das zählt einfach nur die zeilen einer ca 1G großen (einstellbar) datei.

    ausgabe:

    1 100000000 19.906
    2 100000000 19.734
    3 100000000 36.516
    1 100000000 19.765
    2 100000000 19.735
    3 100000000 36.703
    1 100000000 19.75
    2 100000000 19.875
    3 100000000 36.469
    1 100000000 19.75
    2 100000000 19.968
    3 100000000 36.313
    1 100000000 19.859
    2 100000000 19.672
    3 100000000 36.188
    

    ich denke mal, an dem ergebnis gibts wenig zu interpretieren. string ist lahm. fstream und iostream sind gleich schnell.



  • @volkard
    Welchen Compiler bzw. welche Standard-Lib verwendest du? Erhalte mit dem VC 8 andere Ergebnisse:

    1 10000000 1.922
    2 10000000 5.734
    3 10000000 7.891
    1 10000000 1.906
    2 10000000 5.687
    3 10000000 7.891
    [...]
    

    Dateigröße war ca. 100 MB.


Anmelden zum Antworten