Benutzen von 'rdbuf()'



  • #include <fstream>
    #include <iostream>
    
    int main() {
      std::ifstream file("test.txt");
      std::cout << file.rdbuf();
    }
    


  • Gugelmoser schrieb:

    Ich mache es immer so: [...]

    👎



  • Habe das bis jetzt auch immer so gemacht, kannte dass rdbuf() auch noch nicht...

    Gugelmoser schrieb:

    int main()
    {
    	std::ifstream file("test.txt");
    	std::copy( std::istream_iterator<char>(file>>std::noskipws), (std::istream_iterator<char>()), std::ostream_iterator<char>(std::cout) );
    }
    


  • Der istream_iterator, bzw ostream_iterator ist so ziemlich die schlechteste Wahl. Die rdbuf-Variante ist die kürzeste, einfachste und effizienteste Variante. Es gibt übrigens noch einen std::ostreambuf_iterator und std::istreambuf_iterator, die wesentlich weniger overhead haben, als der istream_iterator und ostream_iterator. Es gibt also die Varianten:

    // Variante 1: istream_iterator/ostream_iterator
    std::copy( std::istream_iterator<char>(file>>std::noskipws), (std::istream_iterator<char>()), std::ostream_iterator<char>(std::cout) );
    
    // Variante 2: istream_iterator/ostreambuf_iterator
    std::copy( std::istream_iterator<char>(file>>std::noskipws), (std::istream_iterator<char>()), std::ostreambuf_iterator<char>(std::cout) );
    
    // Variante 3: istreambuf_iterator/ostream_iterator
    std::copy( std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), std::ostream_iterator<char>(std::cout));
    
    // Variante 4: istreambuf_iterator mit ostream_iterator
    std::copy( std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), std::ostreambuf_iterator<char>(std::cout));
    
    // Variante 5: einfach rdbuf
    std::cout << file.rdbuf();
    

    Spaßeshalber habe ich mal die Geschwindigkeit der Varianten untersucht. Ich habe die 5 Varianten in ein Programm eingebaut und mit time getestet. Ich verwende hier Fedora Linux mit g++ 4.7.0 und verwende die Compile-Option -O2. Mein Programm heißt cat und ich teste so:

    time ./cat grosseDateMitCa280MBDaten|md5sum
    

    Das Ergebnis ist so:

    • Variante 1: 13.5s
    • Variante 2: 7.5s
    • Variante 3: 10.4s
    • Variante 4: 0.61s
    • Variante 5: 0.61s

    Interessant finde ich, dass die streambuf_iterator-Variante genauso schnell ist, wie die rdbuf-Variante. Die iostream-Variante ist tatsächlich viiiiel langsamer als die anderen.



  • @tntnet Könntest du deinen Quellcode für die Zeitmessung noch posten pls?


  • Mod

    tntnet schrieb:

    Interessant finde ich, dass die streambuf_iterator-Variante genauso schnell ist, wie die rdbuf-Variante. Die iostream-Variante ist tatsächlich viiiiel langsamer als die anderen.

    Ich bin auch positiv überrascht von der streambuf_iterator-Variante. Dass die normalen Iteratoren eingehen war klar, weil man hier hinter dem copy und dem iterator (unfreiwillig) große, unnötige Komplexität verborgen hat (@gugelmoser: Das ist eine zeichenweise Kopie, falls du es nicht wusstest). Was mich interessieren würde, da du gerade ein Testprogramm fertig hast: Wie verhält sich dazu ein kleiner Puffer (ein paar Kilobyte) mit read und write?



  • SeppJ schrieb:

    @gugelmoser: Das ist eine zeichenweise Kopie, falls du es nicht wusstest.

    Du meinst die Datei wird Zeichen für Zeichen gelesn? Ja das ist mir klar. Ich meinte, ob er sein ganzes Testprogramm posten würde.



  • Also da ihr ja genauso neugierig seid, wie ich, dann hier mal der komplette Quellcode. Und zwar inklusive der vorgeschlagenen Buffer-Variante mit einem 8k buffer, die genauso schnell ist, wie Variante 4 und 5:

    #include <iostream>
    #include <fstream>
    #include <iterator>
    #include <cxxtools/arg.h>
    
    int main(int argc, char* argv[])
    {
      try
      {
        cxxtools::Arg<int> variant(argc, argv, 'v', 1);
        for (int a = 1; a < argc; ++a)
        {
          std::ifstream file(argv[a]);
          switch (variant.getValue())
          {
            case 1:
              std::copy( std::istream_iterator<char>(file>>std::noskipws), (std::istream_iterator<char>()), std::ostream_iterator<char>(std::cout) );
              break;
            case 2:
              std::copy( std::istream_iterator<char>(file>>std::noskipws), (std::istream_iterator<char>()), std::ostreambuf_iterator<char>(std::cout) );
              break;
            case 3:
              std::copy( std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), std::ostream_iterator<char>(std::cout));
              break;
            case 4:
              std::copy( std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), std::ostreambuf_iterator<char>(std::cout));
              break;
            case 5:
              std::cout << file.rdbuf();
              break;
            case 6:
            {
              char buffer[8192];
              while (file.read(buffer, sizeof(buffer)), file.gcount() > 0)
                std::cout.write(buffer, file.gcount());
              break;
            }
          }
        }
      }
      catch (const std::exception& e)
      {
        std::cerr << e.what() << std::endl;
      }
    }
    

    Compiliert habe ich das mit:

    g++ -o cat -O2 cat.cpp
    

    Testen kann ich dann mit:

    time ./cat -v 1 grosseDatei|md5sum
    

    Oder auch alle Varianten in einem Rutsch:

    for v in 1 2 3 4 5 6; do time ./cat -v $v grosseDatei|md5sum; done
    

    Also es gibt keinen Quellcode für die Zeitmessung. Das macht time für mich. Na ja, klar, GNU/Linux ist Open-Source. Irgendwo gibt es die Sourcen zum time Befehl, aber den brauche ich hier sicher nicht zu posten (ach wie ich Linux doch liebe 😉 )

    cxxtools::Arg ist eine Klasse zum extrahieren von Kommandozeilenoptionen, die bei mir in praktisch jedem Programm vor kommt, da sie so praktisch ist.



  • Guten Mittag,
    hier noch ein Programm für Windows-Systeme, das die Geschwindigkeit aller 6 Varianten misst. test.txt ist eine 100 MB große Textdatei.

    Meine Gegebenheiten:
    `

    i7-860 2.80GHz (8 CPUs)

    8 GB RAM

    Windows 7 Prof. 64-Bit

    Visual Studio 2008 Prof.

    Optimierung: /O2

    `

    Quellcode:

    #include <iostream>
    #include <iterator>
    #include <fstream>
    #include <algorithm>
    #include <windows.h>
    #include <time.h>
    using namespace std;
    
    int main()
    {
    	LONGLONG frequency = 0;
    	LONGLONG start     = 0;
    	LONGLONG ende      = 0;
    	double elapsed_variante_1 = 0;
    	double elapsed_variante_2 = 0;
    	double elapsed_variante_3 = 0;
    	double elapsed_variante_4 = 0;
    	double elapsed_variante_5 = 0;
    	double elapsed_variante_6 = 0;
    
    	if( !QueryPerformanceFrequency((LARGE_INTEGER*)&frequency) )
    		return -1;
    
    	// Variante 1: istream_iterator + ostream_iterator
    	{
    		ifstream file("test.txt");
    		ofstream out("variante_1.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		copy( istream_iterator<char>(file>>noskipws), (istream_iterator<char>()), ostream_iterator<char>(out) );
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_1 = (((double)(ende-start))/((double)frequency));
    	}
    
    	// Variante 2: istream_iterator + ostreambuf_iterator
    	{
    		ifstream file("test.txt");
    		ofstream out("variante_2.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		copy( istream_iterator<char>(file>>noskipws), (istream_iterator<char>()), ostreambuf_iterator<char>(out) );
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_2 = (((double)(ende-start))/((double)frequency));
    	}
    
    	// Variante 3: istreambuf_iterator + ostream_iterator
    	{
    		ifstream file("test.txt");
    		ofstream out("variante_3.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		copy( istreambuf_iterator<char>(file), istreambuf_iterator<char>(), ostream_iterator<char>(out) );
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_3 = (((double)(ende-start))/((double)frequency));
    	}
    
    	// Variante 4: istreambuf_iterator + ostreambuf_iterator
    	{
    		ifstream file("test.txt");
    		ofstream out("variante_4.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		copy( istreambuf_iterator<char>(file), istreambuf_iterator<char>(), ostreambuf_iterator<char>(out) );
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_4 = (((double)(ende-start))/((double)frequency));
    	}
    
    	// Variante 5: einfach rdbuf
    	{
    		ifstream file("test.txt");
    		ofstream out("variante_5.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		out << file.rdbuf();
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_5 = (((double)(ende-start))/((double)frequency));
    	}
    
    	// Variante 6: read + write (8192 Byte Blöcke)
    	{
    		ifstream file("test.txt");
    		ofstream out("variante_6.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		char buffer[8192];
    		while( file.read(buffer, sizeof(buffer)), file.gcount()>0 )
    		{
    			out.write(buffer, file.gcount());
    		}
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_6 = (((double)(ende-start))/((double)frequency));
    	}
    
    	cout << endl << "elapsed_variante_1 = " << elapsed_variante_1; // 17,78 Sekunden
    	cout << endl << "elapsed_variante_2 = " << elapsed_variante_2; //  8,97 Sekunden
    	cout << endl << "elapsed_variante_3 = " << elapsed_variante_3; // 10,45 Sekunden
    	cout << endl << "elapsed_variante_4 = " << elapsed_variante_4; //  2,58 Sekunden
    	cout << endl << "elapsed_variante_5 = " << elapsed_variante_5; //  2,53 Sekunden
    	cout << endl << "elapsed_variante_6 = " << elapsed_variante_6; //  0,83 Sekunden
    }
    

    Messergebnisse:
    `

    Variante 1: istream_iterator + ostream_iterator = 17,78 Sekunden

    Variante 2: istream_iterator + ostreambuf_iterator = 8,97 Sekunden

    Variante 3: istreambuf_iterator + ostream_iterator = 10,45 Sekunden

    Variante 4: istreambuf_iterator + ostreambuf_iterator = 2,58 Sekunden

    Variante 5: einfach rdbuf = 2,53 Sekunden

    Variante 6: read + write (8192 Byte Blöcke) = 0,83 Sekunden

    `

    Erkenntnisse:
    - stream_iterator sind extrem langsam.
    - streambuf_iterator und rdbuf sind praktisch gleich schnell.
    - Blockweises kopieren ist am Schnellsten.



  • Was ich auch interessant finde, ist, dass das Kopieren des Dateiinhalts in einen std::vector via std::copy schneller ist, als via std::vector -Konstruktor:

    Quellcode:

    #include <iostream>
    #include <iterator>
    #include <fstream>
    #include <algorithm>
    #include <windows.h>
    #include <time.h>
    #include <vector>
    using namespace std;
    
    int main()
    {
    	LONGLONG frequency = 0;
    	LONGLONG start     = 0;
    	LONGLONG ende      = 0;
    	double elapsed_variante_1 = 0;
    	double elapsed_variante_2 = 0;
    	double elapsed_variante_3 = 0;
    	double elapsed_variante_4 = 0;
    
    	if( !QueryPerformanceFrequency((LARGE_INTEGER*)&frequency) )
    		return -1;
    
    	// Variante 1: istream_iterator + constructor
    	{
    		ifstream file("test.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		vector<char> v( istream_iterator<char>(file>>noskipws), (istream_iterator<char>()) );
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_1 = (((double)(ende-start))/((double)frequency));
    	}
    
    	// Variante 2: istream_iterator + copy
    	{
    		ifstream file("test.txt");
    		ofstream out("variante_2.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		vector<char> v;
    		copy( istream_iterator<char>(file>>noskipws), (istream_iterator<char>()), back_inserter(v) );
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_2 = (((double)(ende-start))/((double)frequency));
    	}
    
    	// Variante 3: istreambuf_iterator + constructor
    	{
    		ifstream file("test.txt");
    		ofstream out("variante_3.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		vector<char> v( istreambuf_iterator<char>(file), (istreambuf_iterator<char>()) );
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_3 = (((double)(ende-start))/((double)frequency));
    	}
    
    	// Variante 4: istreambuf_iterator + copy
    	{
    		ifstream file("test.txt");
    		ofstream out("variante_4.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		vector<char> v;
    		copy( istreambuf_iterator<char>(file), (istreambuf_iterator<char>()), back_inserter(v) );
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_4 = (((double)(ende-start))/((double)frequency));
    	}
    
    	cout << endl << "elapsed_variante_1 = " << elapsed_variante_1; // 9,11 Sekunden
    	cout << endl << "elapsed_variante_2 = " << elapsed_variante_2; // 8,17 Sekunden
    	cout << endl << "elapsed_variante_3 = " << elapsed_variante_3; // 2,76 Sekunden
    	cout << endl << "elapsed_variante_4 = " << elapsed_variante_4; // 2,04 Sekunden
    }
    

    Messergebnisse:
    `

    Variante 1: istream_iterator + constructor = 9,11 Sekunden

    Variante 2: istream_iterator + copy = 8,17 Sekunden

    Variante 3: istreambuf_iterator + constructor = 2,76 Sekunden

    Variante 4: istreambuf_iterator + copy = 2,04 Sekunden

    `


  • Mod

    out schrieb:

    Was ich auch interessant finde, ist, dass das Kopieren des Dateiinhalts in einen std::vector via std::copy schneller ist, als via std::vector -Konstruktor:

    Das ist doch sehr ungewöhnlich. Hast du auch alle Optimierungen an (auch die berüchtigten STL-Range Checks von Visual Studio ausgeschaltet?) und bei mehrfachen Messungen das gleiche Ergebnis erhalten? Auch wenn du die Reihenfolge der Messungen umdrehst?



  • SeppJ schrieb:

    out schrieb:

    Was ich auch interessant finde, ist, dass das Kopieren des Dateiinhalts in einen std::vector via std::copy schneller ist, als via std::vector -Konstruktor:

    Das ist doch sehr ungewöhnlich. Hast du auch alle Optimierungen an (auch die berüchtigten STL-Range Checks von Visual Studio ausgeschaltet?) und bei mehrfachen Messungen das gleiche Ergebnis erhalten? Auch wenn du die Reihenfolge der Messungen umdrehst?

    Jap. Ich habe mit der Optimierung /Ox (alles optimieren) kompiliert, die Messungen umgedreht und nun auch checked iterators deaktiviert (falls du das gemeint hast?). Die Ergebnisse sind gleich geblieben, auch nach mehrmaliger Durchführung.

    #include <iostream>
    #include <iterator>
    #include <fstream>
    #include <algorithm>
    #include <windows.h>
    #include <time.h>
    #include <vector>
    using namespace std;
    
    #define _SECURE_SCL 0 //  disable checked iterators
    
    int main()
    {
    	LONGLONG frequency = 0;
    	LONGLONG start     = 0;
    	LONGLONG ende      = 0;
    	double elapsed_variante_1 = 0;
    	double elapsed_variante_2 = 0;
    	double elapsed_variante_3 = 0;
    	double elapsed_variante_4 = 0;
    
    	if( !QueryPerformanceFrequency((LARGE_INTEGER*)&frequency) )
    		return -1;
    
    	// Variante 2: istream_iterator + copy
    	{
    		ifstream file("test.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		vector<char> v;
    		copy( istream_iterator<char>(file>>noskipws), (istream_iterator<char>()), back_inserter(v) );
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_2 = (((double)(ende-start))/((double)frequency));
    	}
    
    	// Variante 1: istream_iterator + constructor
    	{
    		ifstream file("test.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		vector<char> v( istream_iterator<char>(file>>noskipws), (istream_iterator<char>()) );
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_1 = (((double)(ende-start))/((double)frequency));
    	}
    
    	// Variante 4: istreambuf_iterator + copy
    	{
    		ifstream file("test.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		vector<char> v;
    		copy( istreambuf_iterator<char>(file), (istreambuf_iterator<char>()), back_inserter(v) );
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_4 = (((double)(ende-start))/((double)frequency));
    	}
    
    	// Variante 3: istreambuf_iterator + constructor
    	{
    		ifstream file("test.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		vector<char> v( istreambuf_iterator<char>(file), (istreambuf_iterator<char>()) );
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_3 = (((double)(ende-start))/((double)frequency));
    	}
    
    	cout << endl << "elapsed_variante_1 = " << elapsed_variante_1; // 8,93 Sekunden
    	cout << endl << "elapsed_variante_2 = " << elapsed_variante_2; // 8,27 Sekunden
    	cout << endl << "elapsed_variante_3 = " << elapsed_variante_3; // 2,76 Sekunden
    	cout << endl << "elapsed_variante_4 = " << elapsed_variante_4; // 2,05 Sekunden
    }
    


  • Wäre nett, wenn es jemand auf einem Linux-System nachprüfgen könnte. 🙂



  • #include <iostream>
    #include <iterator>
    #include <fstream>
    #include <algorithm>
    #include <vector>
    #ifdef _WIN32
    #	include <Windows.h>
    #else
    #	include <sys/time.h>
    #	include <unistd.h>
    #endif
    using namespace std;
    
    namespace
    {
    #ifndef _WIN32
    	typedef long long LONGLONG;
    	typedef long long LARGE_INTEGER;
    
    	int QueryPerformanceFrequency(LARGE_INTEGER *f)
    	{
    		*f = 1000;
    		return 1;
    	}
    
    	void QueryPerformanceCounter(LARGE_INTEGER *c)
    	{
    		struct timespec ts = {0};
    		clock_gettime(CLOCK_MONOTONIC, &ts);
    
    		*c =
    			static_cast<LONGLONG>(ts.tv_sec) * 1000 +
    			static_cast<LONGLONG>(ts.tv_nsec) / 1000 / 1000;
    	}
    #endif
    
    	bool ensureTestFile(const std::string &name, size_t size)
    	{
    		{
    			std::ifstream file(name, std::ios::ate);
    			if (file &&
    				(file.tellg() == size))
    			{
    				return true;
    			}
    		}
    
    		std::ofstream file(name, std::ios::binary);
    		static const char content[1UL << 14] = {};
    		if (!file)
    		{
    			return false;
    		}
    
    		for (size_t i = 0; i < size; )
    		{
    			file.write(content,
    				std::min<size_t>(sizeof(content), (size - i)));
    			i += sizeof(content);
    		}
    
    		return true;
    	}
    }
    
    int main()
    {
    	static const auto Mebi = (1UL << 20);
    
    	if (!ensureTestFile("test.txt", 100 * Mebi))
    	{
    		return 1;
    	}
    
    	LONGLONG frequency = 0;
    	LONGLONG start	 = 0;
    	LONGLONG ende	  = 0;
    	double elapsed_variante_1 = 0;
    	double elapsed_variante_2 = 0;
    	double elapsed_variante_3 = 0;
    	double elapsed_variante_4 = 0;
    
    	if( !QueryPerformanceFrequency((LARGE_INTEGER*)&frequency) )
    		return -1;
    
    	// Variante 2: istream_iterator + copy
    	{
    		ifstream file("test.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		vector<char> v;
    		copy( istream_iterator<char>(file>>noskipws), (istream_iterator<char>()), back_inserter(v) );
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_2 = (((double)(ende-start))/((double)frequency));
    	}
    
    	// Variante 1: istream_iterator + constructor
    	{
    		ifstream file("test.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		vector<char> v( istream_iterator<char>(file>>noskipws), (istream_iterator<char>()) );
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_1 = (((double)(ende-start))/((double)frequency));
    	}
    
    	// Variante 4: istreambuf_iterator + copy
    	{
    		ifstream file("test.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		vector<char> v;
    		copy( istreambuf_iterator<char>(file), (istreambuf_iterator<char>()), back_inserter(v) );
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_4 = (((double)(ende-start))/((double)frequency));
    	}
    
    	// Variante 3: istreambuf_iterator + constructor
    	{
    		ifstream file("test.txt");
    		QueryPerformanceCounter((LARGE_INTEGER*)&start);
    		vector<char> v( istreambuf_iterator<char>(file), (istreambuf_iterator<char>()) );
    		QueryPerformanceCounter((LARGE_INTEGER*)&ende);
    		elapsed_variante_3 = (((double)(ende-start))/((double)frequency));
    	}
    
    	cout << "elapsed_variante_1 = " << elapsed_variante_1 << endl;
    	cout << "elapsed_variante_2 = " << elapsed_variante_2 << endl;
    	cout << "elapsed_variante_3 = " << elapsed_variante_3 << endl;
    	cout << "elapsed_variante_4 = " << elapsed_variante_4 << endl;
    }
    
    $ /usr/lib/gcc-snapshot/bin/g++ --version
    g++ (Ubuntu/Linaro 20120314-0ubuntu2) 4.8.0 20120314 (experimental) [trunk revision 185382]
    [...]
    $ /usr/lib/gcc-snapshot/bin/g++ main.cpp -omain -std=c++0x -lrt -O3
    $ ./main 
    elapsed_variante_1 = 3.372
    elapsed_variante_2 = 3.446
    elapsed_variante_3 = 0.922
    elapsed_variante_4 = 0.905
    


  • Danke TyRoXx. Unterm Strich kommt es also praktisch auf dasselbe heraus. Trotzdem interessant, finde ich. Hätte eher gedacht, dass std::vector -Konstruktor ein bisschen deutlicher vorne liegen würde.



  • out schrieb:

    if( !QueryPerformanceFrequency((LARGE_INTEGER*)&frequency) )
    

    Was soll dieser Müll-Cast denn hier?
    Willst damit wohl eine Compilerwarnung zudecken, was glaubst du wohl, warum der Compiler die Warnung ausgibt?
    Richtig! Weil der Compiler Ahnung hat im Gegensatz zu dir. Zeigercasts sind prinzipiell schlecht und deuten allermeistens auf fehlerhaftes Programmdesign hin.



  • out schrieb:

    Meine Gegebenheiten:
    `

    i7-860 2.80GHz (8 CPUs)

    8 GB RAM

    Windows 7 Prof. 64-Bit

    Visual Studio 2008 Prof.

    Optimierung: /O2

    `

    Messergebnisse:
    `

    Variante 1: istream_iterator + ostream_iterator = 17,78 Sekunden

    Variante 2: istream_iterator + ostreambuf_iterator = 8,97 Sekunden

    Variante 3: istreambuf_iterator + ostream_iterator = 10,45 Sekunden

    Variante 4: istreambuf_iterator + ostreambuf_iterator = 2,58 Sekunden

    Variante 5: einfach rdbuf = 2,53 Sekunden

    Variante 6: read + write (8192 Byte Blöcke) = 0,83 Sekunden

    `

    Lahme Krücke 😉
    `elapsed_variante_1 = 10.3109

    elapsed_variante_2 = 4.85142

    elapsed_variante_3 = 6.86091

    elapsed_variante_4 = 1.5387

    elapsed_variante_5 = 1.3171

    elapsed_variante_6 = 0.427581`



  • Swordfish schrieb:

    out schrieb:

    Meine Gegebenheiten:
    `

    i7-860 2.80GHz (8 CPUs)

    8 GB RAM

    Windows 7 Prof. 64-Bit

    Visual Studio 2008 Prof.

    Optimierung: /O2

    `

    Messergebnisse:
    `

    Variante 1: istream_iterator + ostream_iterator = 17,78 Sekunden

    Variante 2: istream_iterator + ostreambuf_iterator = 8,97 Sekunden

    Variante 3: istreambuf_iterator + ostream_iterator = 10,45 Sekunden

    Variante 4: istreambuf_iterator + ostreambuf_iterator = 2,58 Sekunden

    Variante 5: einfach rdbuf = 2,53 Sekunden

    Variante 6: read + write (8192 Byte Blöcke) = 0,83 Sekunden

    `

    Lahme Krücke 😉
    `elapsed_variante_1 = 10.3109

    elapsed_variante_2 = 4.85142

    elapsed_variante_3 = 6.86091

    elapsed_variante_4 = 1.5387

    elapsed_variante_5 = 1.3171

    elapsed_variante_6 = 0.427581`

    Hier sind meine Ergebnisse:
    elapsed_variante_1 = 4.313
    elapsed_variante_2 = 1.719
    elapsed_variante_3 = 3.135
    elapsed_variante_4 = 0.092
    elapsed_variante_5 = 0.091
    elapsed_variante_6 = 0.083
    Warum ist bei mir die schnellste Variante um den Faktor 5 schneller, als Deine schnellste?

    Übrigens: Intel i5, Fedora 17, x64_64 auf Intel i5.
    Ist Linux an der Stelle jetzt so viel schneller?



  • Du musst das relativ sehen. Caching, Festplattengeschwindigkeit etc machen einen großen Unterschied.



  • Was passiert wenn man Variante 6 als erstes testet? Caching könnte die Ergebnisse verfälschen.


Anmelden zum Antworten