Skip navigation

I’m testing a few C/C++ funcs through having them write out 100,000 lines of data (total amounting to about 3MB) to a file.

The results: Building these with Visual Studio 2005 VC++ on Win 32:

fprintf is faster than ofstream

(fprintf nearly 2x as fast as ofstream on my machine)

fwrite is marginally faster than fprintf

(fwrite about 1.1x as fast as fprintf on my machine)

// OFSTREAM IS SLOW!!

#include <fstream>
using namespace std;

#include <stdio.h>
#include <windows.h>

LARGE_INTEGER   ticksPerSecond;
LARGE_INTEGER   time1;
LARGE_INTEGER   time2;

float floatDiffTime;
const int runs = 100000;

int main()
{
    ////////////////
    // Get the speed of the CPU
    QueryPerformanceFrequency( &ticksPerSecond );
    printf( "Your computer does %lld ticks per second\n", ticksPerSecond.QuadPart );
    // %lld means type "long long" int, which is the
    // 64 bit int which is what we want here.

    // define some random valued variables to use
    // in the print statements
    int a    = 5;
    double b = 9.2919e92;
    char c   = 'x';
    char * d = "blah blah blah";


    // test start:  open a file to write to
    FILE * outfile = fopen( "testfile.txt", "w" );

    /////////////////////
    // START timing
    QueryPerformanceCounter( &time1 );

    // test fprintf(), run 100000 times!
    for(int i = 0; i < runs; i++)
    {
        fprintf(outfile, "blah %i %f %c %s\n", a, b, c, d );
        fflush( outfile );  // flush to be fair
    }

    ////////////////////
    // STOP timing
    QueryPerformanceCounter( &time2 );

    // get the difference between time1 and time2,
    // and that is how long the for loop took to run.
    floatDiffTime = ((float)time2.QuadPart - time1.QuadPart)/ticksPerSecond.QuadPart;
    printf( "fprintf took %f seconds\n", floatDiffTime );

    fclose( outfile );  // close up, so we
    // can proceed to start over with
    // ofstream test.


    ////////////////
    // testing ofstream()
    ofstream out( "oftestout.txt" );

    ////////////////////
    // START timing
    QueryPerformanceCounter( &time1 );
    //
    ////////////////////

    // test ofstream, run 100000 times!
    for(int i = 0; i < runs; i++)
    {
        out << "blah " << a << " " << b << " " << c << " " << d << endl;
        out.flush();  // flush to be fair
    }

    ////////////////////
    // STOP timing
    QueryPerformanceCounter( &time2 );
    //
    ////////////////////

    // get the difference between time1 and time2,
    // and that is how long the for loop took to run.
    floatDiffTime = ((float)time2.QuadPart - time1.QuadPart)/ticksPerSecond.QuadPart;
    printf( "ofstream took %f seconds\n", floatDiffTime );

    out.close();

    return 0;
}

But what about fprintf() vs fwrite()?

Place your bets!

// what's faster, fwrite or fprintf?

#include <stdio.h>
#include <stdlib.h>

#include <windows.h>

LARGE_INTEGER   ticksPerSecond;
LARGE_INTEGER   time1;
LARGE_INTEGER   time2;

float floatDiffTime;
const int runs = 100000;
char buf[255];      // create a buffer for fwrite to use

int main()
{
    ////////////////
    // Get the speed of the CPU
    QueryPerformanceFrequency( &ticksPerSecond );
    printf( "Your computer does %lld ticks per second\n", ticksPerSecond.QuadPart );
    // %lld means type "long long" int, which is the
    // 64 bit int which is what we want here.

    // define some random valued variables to use
    // in the print statements
    int a    = 5;
    double b = 9.2919e92;
    char c   = 'x';
    char * d = "blah blah blah";


    // test start:  open a file to write to
    FILE * outfile = fopen( "testfile.txt", "w" );

    /////////////////////
    // START timing
    QueryPerformanceCounter( &time1 );

    // test fprintf(), run 100000 times!
    for(int i = 0; i < runs; i++)
    {
        //fprintf(outfile, "blah %i %f %c %s\n", a, b, c, d );

        // making fprintf() print a single string generated
        // by sprintf() to equalize the test
        sprintf( buf, "blah %i %f %c %s\n", a, b, c, d );   // its only fair!
        fprintf( outfile, "%s", buf );

        fflush(outfile);    // flush after going to the toilet
    }

    ////////////////////
    // STOP timing
    QueryPerformanceCounter( &time2 );

    // get the difference between time1 and time2,
    // and that is how long the for loop took to run.
	floatDiffTime = ((float)time2.QuadPart - time1.QuadPart)/ticksPerSecond.QuadPart;
    printf( "fprintf took %f seconds\n", floatDiffTime );

    fclose( outfile );  // close up, so we
    // can proceed to start over with
    // fwrite test.


    ////////////////
    // testing fwrite()
    outfile = fopen( "testfile.txt", "w" );

    ////////////////////
    // START timing
    QueryPerformanceCounter( &time1 );
    //
    ////////////////////

    // test fwrite(), run 100000 times!
    for(int i = 0; i < runs; i++)
    {
        // fwrite needs a single string to write from,
        // so use sprintf to copy to a buffer
        sprintf( buf, "blah %i %f %c %s\n", a, b, c, d );
        fwrite( buf, 1, strlen( buf ), outfile );
        fflush(outfile);    // flush
    }

    ////////////////////
    // STOP timing
    QueryPerformanceCounter( &time2 );
    //
    ////////////////////

    // get the difference between time1 and time2,
    // and that is how long the for loop took to run.
	floatDiffTime = ((float)time2.QuadPart - time1.QuadPart)/ticksPerSecond.QuadPart;
    printf( "fwrite() took %f seconds\n", floatDiffTime );


    fclose( outfile );
    return 0;
}

In my tests here, fwrite() was faster, even though using fwrite requires an extra call to strlen().

Anyway, this was just for fun. For all intents and purposes, fprintf() is pretty much the same speed as fwrite(). BUT fprintf is DEFINITELY much faster than ofstream!

Visual Studio 2005 project files for fprintf vs ofstream test hosted by esnips (thanks esnips!)

Advertisements

7 Comments

    • Stalker
    • Posted March 27, 2008 at 7:24 pm
    • Permalink

    The same test under linux (2.6 kernel, gcc 3.5.3 tho i doubt that matters) return almost equal speeds (fprintf is still a tad faster tho). However i personally prefer fstream as it is much much easier to use, so unless you’ll be doing heavy I/O i see no reason not to use it.

    • Nicolas
    • Posted November 21, 2009 at 3:02 am
    • Permalink

    What appen when compiling code for speed (-O3 with GCC) ?
    Does the compiler compensate the slowliness of C++ over C ?

  1. My experience is similar: in my test fprintf() is 4-5 times faster than ofstream (writing 500’000 lines of double’s to a file).

    • Rolf
    • Posted April 13, 2012 at 9:12 am
    • Permalink

    Forgot to say that I use C++Builder (Borland compiler)

    • Anonymous
    • Posted April 27, 2012 at 4:12 pm
    • Permalink

    endl implies a flush on buffered streams, so I guess you’ve let ofstream flush twice each time.

    • Anonymous
    • Posted September 8, 2012 at 9:57 am
    • Permalink

    fstream was faster on linux 3.2.0-23 32-bit using GCC 4.6.3.
    fprintf took 2.330000 seconds
    ofstream took 1.150000 seconds
    fwrite() took 2.430000 second

    • RJB
    • Posted December 31, 2013 at 10:47 pm
    • Permalink

    Another test that would be interesting is to compare fwrite() and fprintf() by sending larger data sets to the
    OS file IO subsystem to explore the differences in how this is handled:
    //Test fprintf
    char buf[HUGE_NUMBER];
    int index = 0;

    //clock measurement here
    memset(buf,”, HUGE_NUMBER);
    for(i=0; i= HUGE_NUMBER) {
    fprintf(outfile, “%s”, buf );
    index = 0;
    memset(buf,”, HUGE_NUMBER);
    }
    }
    fflush(outfile)
    //clock measurement here

    //Test fwrite
    memset(buf,”, HUGE_NUMBER);
    for(i=0; i= HUGE_NUMBER) {
    fwrite( buf, 1, strlen( buf ), outfile );
    index = 0;
    memset(buf,”, HUGE_NUMBER);
    }
    }
    fflush(outfile)
    //clock measurement here

    This would shed some light on how the underlying I/O buffering is used, and whether you can help optimize it to the large data set by requesting large data writes (for example, if HUGE_NUMBER is many times the threshold at which the OS will execute pending write operations)


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: