Labels: c++ (6) scripting (4) the perfect project (3) coding (1) firefox (1) idea (1)

Saturday, February 3, 2007

File reading contest

Sample output: >streamReadingContest_StlPort.exe 50mb
reading 50mb...
reserveDistanceCopyStreamItersViaInserter 0.4
seekAndLoadArray 0.75
seekAndLoadVector 0.8
seekAndLoadVectorReserve 0.8
putInStringStream 3.8
assignToStreamItersInterval 0.8
reserveAssignToStreamItersInterval 0.3
copyStreamItersViaInserter 0.75

>streamReadingContest_home.exe 50mb
reading 50mb...
reserveDistanceCopyStreamItersViaInserter 0.5
seekAndLoadArray 2.95
seekAndLoadVector 2.95
seekAndLoadVectorReserve 3
putInStringStream 4.45
assignToStreamItersInterval 3.65
reserveAssignToStreamItersInterval 0.45
copyStreamItersViaInserter 3.25
Looks like the winner is reserveAssignToStreamItersInterval. =)
#include <fstream>
#include <sstream>
#include <iostream>
#include <string>
#include <vector>
#include <ctime>

typedef std::string FileName;

typedef void (LoadFunc) (const FileName& fileName, std::string& result);

void seekAndLoadArray (const FileName& fileName, std::string& result)
{
   std::ifstream inFile( fileName.c_str(), std::ios::binary );

   inFile.seekg( 0, std::ios_base::end );
   unsigned long fileSize = inFile.tellg();
   inFile.seekg( 0, std::ios_base::beg );

   char* buf = new char[ fileSize ];
   inFile.read( buf, fileSize );
   result.assign( buf, buf + fileSize );
   delete[] buf;
}

void seekAndLoadVector (const FileName& fileName, std::string& result)
{
   std::ifstream inFile( fileName.c_str(), std::ios::binary );

   inFile.seekg( 0, std::ios_base::end );
   unsigned long fileSize = inFile.tellg();
   inFile.seekg( 0, std::ios_base::beg );

   std::vector<char> buf( fileSize );
                     buf.resize( fileSize );

   inFile.read( &buf[0], fileSize );
   result.assign( buf.begin(), buf.end() );
}

void seekAndLoadVectorReserve (const FileName& fileName, std::string& result)
{
   std::ifstream inFile( fileName.c_str(), std::ios::binary );

   inFile.seekg( 0, std::ios_base::end );
   unsigned long fileSize = inFile.tellg();
   inFile.seekg( 0, std::ios_base::beg );

   std::vector<char> buf( fileSize );
                     buf.resize( fileSize );

   inFile.read( &buf[0], fileSize );
   result.reserve( fileSize );
   result.assign( buf.begin(), buf.end() );
}

void putInStringStream (const FileName& fileName, std::string& result)
{
   std::ifstream inFile( fileName.c_str(), std::ios::binary );
   std::ostringstream resultStringStream;

   char ch;
   while (inFile.get( ch ))
   {
      resultStringStream.put( ch );
   }

   result = resultStringStream.str();
}

void assignToStreamItersInterval (const FileName& fileName, std::string& result)
{
   std::ifstream inFile (fileName.c_str(), std::ios::binary);
   std::istreambuf_iterator<char> b( inFile ), e;
   result.assign( b, e );
}

void reserveAssignToStreamItersInterval (const FileName& fileName, std::string& result)
{
   std::ifstream inFile (fileName.c_str(), std::ios::binary);
   std::istreambuf_iterator<char> b( inFile ), e;
   result.reserve( std::distance( b, e ) );
   result.assign( b, e );
}

void copyStreamItersViaInserter (const FileName& fileName, std::string& result)
{
   std::ifstream inFile (fileName.c_str(), std::ios::binary);
   std::istreambuf_iterator<char> b( inFile ), e;
   result.clear();
   std::copy( b, e, std::back_inserter( result ) );
}

void reserveDistanceCopyStreamItersViaInserter (const FileName& fileName, std::string& result)
{
   std::ifstream inFile (fileName.c_str(), std::ios::binary);
   std::istreambuf_iterator<char> b( inFile ), e;
   result.resize( std::distance( b, e ) );
   std::copy( b, e, result.begin() );
}

FileName fileName;

void testLoad (LoadFunc loader, const std::string& loaderName)
{
   const int NumTests = 20;
   double acc = 0.0;
   std::cout << loaderName << " ";

   for (int i = 0; i < NumTests; ++i)
   {
      std::string result;

      time_t start = std::time( 0 );
      loader( fileName, result );
      time_t end = std::time( 0 );

      acc += end - start;
   }
   std::cout << acc / NumTests << "\n";
}

void main (int argc, char **argv)
{
   if (argc > 1)
   {
      fileName = argv[1];

      std::cout << "reading " << fileName << "...\n";

      testLoad( reserveDistanceCopyStreamItersViaInserter, "reserveDistanceCopyStreamItersViaInserter" );
      testLoad( seekAndLoadArray, "seekAndLoadArray" );
      testLoad( seekAndLoadVector, "seekAndLoadVector" );
      testLoad( seekAndLoadVectorReserve, "seekAndLoadVectorReserve" );
      testLoad( putInStringStream, "putInStringStream" );
      testLoad( assignToStreamItersInterval, "assignToStreamItersInterval" );
      testLoad( reserveAssignToStreamItersInterval, "reserveAssignToStreamItersInterval" );
      testLoad( copyStreamItersViaInserter, "copyStreamItersViaInserter" );
   }
   else
   {
      std::cout << "Expected filename as a parameter!";
   }
}

No comments: