By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,652 Members | 989 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,652 IT Pros & Developers. It's quick & easy.

C++ vs C when it comes to speed...

P: n/a
I am sure this topic has been discussed a thousand times and I read a
few things about it today on the net. I also want to say I am trying
to start a polemic here, I am just curious and willint to learn and
improve the way I am approaching some coding issues that I have at the
moment. I use C++ programming for my work, but I am not a developper
so please be patient & tolerant in your answers ;-)

Okay for the last few days I have been struggling with mixing some C
and C++ code. I usually try to make my code C++ all the way through.
Recently because I had to implement some old C specs I decided for
some weird reasons to mix C and C++ code. Not a good thing to do I
know. Anyway I really struggled with the idea for the last few days
and spend quite some time going back & fort different versions of the
code, some had more C than C++, some where only C++. I must say that
in what I am doing, execution SPEED is important.

So today I decided to do this very simple test. I wrote the same
functionalities but one version is C++ the other C and run these
functions in a loop (10 000 times).

The C++ versions takes 5 seconds
The C version takes 1 second to execute

This a big difference. I realised that the difference is mostly coming
in the push_back function of the std::vector class. If I comment that
line out, the C++ code runs in 1 second. I used to find the STL lib
very very convenient but I never realised they had such an impact of
the application performances. Here is the program that I used for the
test... Maybe I am doing something wrong so I apologize in advance.

As I said in the pre-ambule of the post, I am trying to be
constructive. The feedbacks I would like to have are more:
1/ i am doing something wrong in the C++ implementation that would
slow it down.
2/ is it a good thing to do to use C coding in a C++ app if speed is
an issue and I want the app to run as fast as it could.

Thanks everyone.

// 1. comparing speed C vs C++
// Running on Max OS X, Power PC G4, 1.5 Ghz
// c++ -o ribparser ribparser.cpp

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

#include <fstream>
#include <string>
#include <vector>

#include <ctime>

class RibParser
{
std::string m_ribFile;
public:
std::ifstream ifs;
RibParser( std::string ribFile ) : m_ribFile( ribFile )
{
char rixm[512];
try
{
ifs.open( ribFile.c_str() );
if ( ifs.fail() )
{
sprintf( rixm, "%s: Can't open\n", ribFile.c_str() );
throw( rixm );
}
}
catch( char *rixm )
{
printf( rixm );
ifs.close();
exit( 0 );
}
int ch;
std::vector<chartoken;
while( ! ifs.eof() )
{
ch = ifs.get();
// comment this line out and the app runs in 1 second
token.push_back( ch );
}
}
~RibParser()
{
ifs.close();
}
};

static const size_t ARRAY_INCR = 8;

void RibParserC( const char *ribFile )
{
char *token;
size_t tokenByteSize = 0;
size_t tokenArraySize = ARRAY_INCR;
FILE *source;
if ( ( source = fopen( ribFile, "r" ) ) == NULL )
{
printf( "%s: Can't open\n", ribFile );
fclose( source );
exit( 0 );
}
token = (char*)malloc( ARRAY_INCR );
int ch;
do
{
ch = fgetc( source );
token[tokenByteSize] = ch;
tokenByteSize++;
if ( ( tokenByteSize % tokenArraySize ) == 0 )
{
token = (char*)realloc( token, tokenArraySize + ARRAY_INCR );
tokenArraySize += ARRAY_INCR;
}
} while ( ch != EOF );
fclose( source );
free( token );
}

int main( int argc, char ** argv )
{
time_t start, end;
time( &start );
for ( size_t i = 0; i < 10000; ++i )
{
RibParser ribParser( "/Users/jean-colas/Desktop/comment.rib" );
}
time( &end );
double diff = difftime( end, start );
printf( "seconds %f %d\n", diff, CLOCKS_PER_SEC );

time( &start );
for ( size_t i = 0; i < 10000; ++i )
{
RibParserC( "/Users/jean-colas/Desktop/comment.rib" );
}
time( &end );
diff = difftime( end, start );
printf( "seconds %f %d\n", diff, CLOCKS_PER_SEC );

return 0;
}

/////

Mar 1 '07 #1
Share this Question
Share on Google+
8 Replies


P: n/a

<ma*****@yahoo.comwrote in message
news:11*********************@z35g2000cwz.googlegro ups.com...
>I am sure this topic has been discussed a thousand times
Yes, and the answer is the same: Neither language has
a 'speed', only specific implementations can be measured
for speed.

More below.
and I read a
few things about it today on the net. I also want to say I am trying
to start a polemic here, I am just curious and willint to learn and
improve the way I am approaching some coding issues that I have at the
moment. I use C++ programming for my work, but I am not a developper
so please be patient & tolerant in your answers ;-)

Okay for the last few days I have been struggling with mixing some C
and C++ code. I usually try to make my code C++ all the way through.
Recently because I had to implement some old C specs I decided for
some weird reasons to mix C and C++ code. Not a good thing to do I
know. Anyway I really struggled with the idea for the last few days
and spend quite some time going back & fort different versions of the
code, some had more C than C++, some where only C++. I must say that
in what I am doing, execution SPEED is important.

So today I decided to do this very simple test. I wrote the same
functionalities but one version is C++ the other C and run these
functions in a loop (10 000 times).

The C++ versions takes 5 seconds
The C version takes 1 second to execute
Since you don't show both versions, we can't know how
closely the algorithms for each match one another.
>
This a big difference. I realised that the difference is mostly coming
in the push_back function of the std::vector class. If I comment that
line out, the C++ code runs in 1 second. I used to find the STL lib
very very convenient but I never realised they had such an impact of
the application performances. Here is the program that I used for the
test... Maybe I am doing something wrong so I apologize in advance.

As I said in the pre-ambule of the post, I am trying to be
constructive. The feedbacks I would like to have are more:
1/ i am doing something wrong in the C++ implementation that would
slow it down.
I'll guess yes, probably, if you've done what I think in
the C version: preallocate storage (which you did not do
in the C++ code below).
2/ is it a good thing to do to use C coding in a C++ app
No, never. They are two separate, distinct languages, each
with its own 'best practices'. If you want a C program, write it
in C. If you want a C++ program, write it in C++.

if speed is
an issue
Almost without exception, the largest factor concerning time
performance is algorithms, not language or 'clever tricks'.
Note that with the C++ standard library, all the algorithm
details are not readily apparent.
and I want the app to run as fast as it could.

Thanks everyone.

// 1. comparing speed C vs C++
I suspect you're not comparing the same procedures between
the languages.

More below.
// Running on Max OS X, Power PC G4, 1.5 Ghz
// c++ -o ribparser ribparser.cpp

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

#include <fstream>
#include <string>
#include <vector>

#include <ctime>

class RibParser
{
std::string m_ribFile;
public:
std::ifstream ifs;
RibParser( std::string ribFile ) : m_ribFile( ribFile )
{
char rixm[512];
try
{
ifs.open( ribFile.c_str() );
if ( ifs.fail() )
{
sprintf( rixm, "%s: Can't open\n", ribFile.c_str() );
throw( rixm );
}
}
catch( char *rixm )
{
printf( rixm );
ifs.close();
exit( 0 );
}
int ch;
In your C version, I suspect you've defined or allocated an array
whose
size can accomodate the input. If so, to more closely approximate
that
with this program, change the following line:

std::vector<chartoken;
to:

std::vector<chartoken(number_of_array_elements_in_ C_program);
while( ! ifs.eof() )
Change the above line to:

while(ifs)
{
ch = ifs.get();
// comment this line out and the app runs in 1 second
token.push_back( ch );
}
}
~RibParser()
{
ifs.close();
}
};

static const size_t ARRAY_INCR = 8;

void RibParserC( const char *ribFile )
{
char *token;
size_t tokenByteSize = 0;
size_t tokenArraySize = ARRAY_INCR;
FILE *source;
if ( ( source = fopen( ribFile, "r" ) ) == NULL )
{
printf( "%s: Can't open\n", ribFile );
fclose( source );
exit( 0 );
}
token = (char*)malloc( ARRAY_INCR );
int ch;
do
{
ch = fgetc( source );
token[tokenByteSize] = ch;
tokenByteSize++;
if ( ( tokenByteSize % tokenArraySize ) == 0 )
{
token = (char*)realloc( token, tokenArraySize + ARRAY_INCR );
tokenArraySize += ARRAY_INCR;
}
} while ( ch != EOF );
fclose( source );
free( token );
}

int main( int argc, char ** argv )
{
time_t start, end;
time( &start );
for ( size_t i = 0; i < 10000; ++i )
{
RibParser ribParser( "/Users/jean-colas/Desktop/comment.rib" );
}
time( &end );
double diff = difftime( end, start );
printf( "seconds %f %d\n", diff, CLOCKS_PER_SEC );

time( &start );
for ( size_t i = 0; i < 10000; ++i )
{
RibParserC( "/Users/jean-colas/Desktop/comment.rib" );
}
time( &end );
diff = difftime( end, start );
printf( "seconds %f %d\n", diff, CLOCKS_PER_SEC );

return 0;
}

/////
With the small change I indicated above, I suspect you'll see
a dramatic improvement in time performance.

-Mike
Mar 1 '07 #2

P: n/a
ma*****@yahoo.com wrote:
I am sure this topic has been discussed a thousand times and I read a
few things about it today on the net. I also want to say I am trying
to start a polemic here, I am just curious and willint to learn and
improve the way I am approaching some coding issues that I have at the
moment. I use C++ programming for my work, but I am not a developper
so please be patient & tolerant in your answers ;-)

Okay for the last few days I have been struggling with mixing some C
and C++ code. I usually try to make my code C++ all the way through.
Recently because I had to implement some old C specs I decided for
some weird reasons to mix C and C++ code. Not a good thing to do I
know. Anyway I really struggled with the idea for the last few days
and spend quite some time going back & fort different versions of the
code, some had more C than C++, some where only C++. I must say that
in what I am doing, execution SPEED is important.

So today I decided to do this very simple test. I wrote the same
functionalities but one version is C++ the other C and run these
functions in a loop (10 000 times).

The C++ versions takes 5 seconds
The C version takes 1 second to execute

This a big difference. I realised that the difference is mostly coming
in the push_back function of the std::vector class. If I comment that
line out, the C++ code runs in 1 second. I used to find the STL lib
very very convenient but I never realised they had such an impact of
the application performances. Here is the program that I used for the
test... Maybe I am doing something wrong so I apologize in advance.

As I said in the pre-ambule of the post, I am trying to be
constructive. The feedbacks I would like to have are more:
1/ i am doing something wrong in the C++ implementation that would
slow it down.
2/ is it a good thing to do to use C coding in a C++ app if speed is
an issue and I want the app to run as fast as it could.

Thanks everyone.

// 1. comparing speed C vs C++
// Running on Max OS X, Power PC G4, 1.5 Ghz
// c++ -o ribparser ribparser.cpp

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

#include <fstream>
#include <string>
#include <vector>

#include <ctime>

class RibParser
{
std::string m_ribFile;
public:
std::ifstream ifs;
RibParser( std::string ribFile ) : m_ribFile( ribFile )
{
char rixm[512];
try
{
ifs.open( ribFile.c_str() );
if ( ifs.fail() )
{
sprintf( rixm, "%s: Can't open\n", ribFile.c_str() );
throw( rixm );
}
}
catch( char *rixm )
{
printf( rixm );
ifs.close();
exit( 0 );
}
int ch;
std::vector<chartoken;
while( ! ifs.eof() )
{
ch = ifs.get();
// comment this line out and the app runs in 1 second
token.push_back( ch );
}
}
~RibParser()
{
ifs.close();
}
};

static const size_t ARRAY_INCR = 8;

void RibParserC( const char *ribFile )
{
char *token;
size_t tokenByteSize = 0;
size_t tokenArraySize = ARRAY_INCR;
FILE *source;
if ( ( source = fopen( ribFile, "r" ) ) == NULL )
{
printf( "%s: Can't open\n", ribFile );
fclose( source );
exit( 0 );
}
token = (char*)malloc( ARRAY_INCR );
int ch;
do
{
ch = fgetc( source );
token[tokenByteSize] = ch;
tokenByteSize++;
if ( ( tokenByteSize % tokenArraySize ) == 0 )
{
token = (char*)realloc( token, tokenArraySize + ARRAY_INCR );
tokenArraySize += ARRAY_INCR;
}
} while ( ch != EOF );
fclose( source );
free( token );
}

int main( int argc, char ** argv )
{
time_t start, end;
time( &start );
for ( size_t i = 0; i < 10000; ++i )
{
RibParser ribParser( "/Users/jean-colas/Desktop/comment.rib" );
}
time( &end );
double diff = difftime( end, start );
printf( "seconds %f %d\n", diff, CLOCKS_PER_SEC );

time( &start );
for ( size_t i = 0; i < 10000; ++i )
{
RibParserC( "/Users/jean-colas/Desktop/comment.rib" );
}
time( &end );
diff = difftime( end, start );
printf( "seconds %f %d\n", diff, CLOCKS_PER_SEC );

return 0;
}

/////
I couldn't reproduce your results because I didn't have
"/Users/jean-colas/Desktop/comment.rib". So instead I used a 50KB chunk
of random data from /dev/urandom.

Results:
seconds 28.000000 1000000
seconds 26.000000 1000000

After turning on optimization (g++ -O3 -o ribparser ribparser.cpp):
seconds 17.000000 1000000
seconds 23.000000 1000000

So I would claim that your implementations are competitive, at least
given the input I provided.

I have some guesses as to why you are seeing what you are seeing. A
function call:
token.push_back( ch );

has a much larger overhead than an assignment:
token[tokenByteSize] = ch;

A good compiler will probably get rid of most/all of that overhead when
you turn on optimizations.

Another observation is that your C implementation potentially has
quadratic time (depending on how realloc is implemented), while your C++
implementation has linear time. On a large enough input, I would expect
the C++ version to pull far ahead. This has nothing to do with the
language itself, though, but rather the quality of the algorithm you use.

--
Alan Johnson
Mar 1 '07 #3

P: n/a

Mike
Since you don't show both versions, we can't know how
closely the algorithms for each match one another.
The code that I posted has the 2 versions. There is a C++ class called
RibParser and a 'C function RibParserC.
They are 2 loops, one for the C++ class, one calling the C function.
>
In your C version, I suspect you've defined or allocated an array
whose
size can accomodate the input. If so, to more closely approximate
that
with this program, change the following line:
std::vector<chartoken;

to:

std::vector<chartoken(number_of_array_elements_in_ C_program);
while( ! ifs.eof() )

Change the above line to:

while(ifs)
I have done these changes and with the optimisation flag the 2
versions now seem to run in almost the same time (less than 1 second).
Without the O flag the C++ runs in 4 seconds and C version in 1 second
but that doesn't matter as using a the O flag is a normal thing to do
at the end anyway. So I guess, that answers my question. I can get the
same speed out of the 2 versions.

Thanks -

Mar 1 '07 #4

P: n/a
Thanks everyone for your help, time & expertise. I think I have a
clear answer to my problem and know what to do.
cheers -

Mar 1 '07 #5

P: n/a

<ma*****@yahoo.comwrote in message
news:11*********************@z35g2000cwz.googlegro ups.com...
The C++ versions takes 5 seconds
The C version takes 1 second to execute

You did not compare identical code.
A virtual method table implemented in C is slower or the same speed as a
virtual method table of a C++ class.
Identical C-code compiles to identical speed using one or the other
compiler.
C++ may give better performance than C, since it heavily using inlining
functionality.
Consider the example of sorting a vector:
Using the STL library much of the comparision will be inlined
-- using qsort you need to pass a function which is not going to be inlined.
In C++ you always have to freedom to go back and implement things by hand if
the provided functionality is too slow.
realloc() is always going to be faster than plain new/delete, since this
functionality does not exist with new/delete.
Use profiling and then consider if the resulting performance is acceptable.

Mar 1 '07 #6

P: n/a
On Mar 1, 5:11 pm, "mast...@yahoo.com" <mast...@yahoo.comwrote:
Okay for the last few days I have been struggling with mixing some C
and C++ code. I usually try to make my code C++ all the way through.
I'm not really sure what this means. Both programs you posted were
valid C++. That's the beauty of the language. You can write
procedural, OO, and generic code. Can't remember the last non-trival
program I wrote that didn't have all three.

Mar 2 '07 #7

P: n/a
On Mar 2, 11:34 am, "Mike Wahler" <mkwah...@mkwahler.netwrote:
<mast...@yahoo.comwrote in message
while( ! ifs.eof() )

Change the above line to:

while(ifs)
{
ch = ifs.get();
// comment this line out and the app runs in 1 second
token.push_back( ch );
}
That would still be wrong. After the last character has been read,
the stream is still good. It does not go to a fail state until after
a read has failed. This code will push a garbage character onto the
end of the vector, every time.

Mar 2 '07 #8

P: n/a

"Old Wolf" <ol*****@inspire.net.nzwrote in message
news:11*********************@v33g2000cwv.googlegro ups.com...
On Mar 2, 11:34 am, "Mike Wahler" <mkwah...@mkwahler.netwrote:
><mast...@yahoo.comwrote in message
while( ! ifs.eof() )

Change the above line to:

while(ifs)
{
ch = ifs.get();
// comment this line out and the app runs in 1 second
token.push_back( ch );
}

That would still be wrong. After the last character has been read,
the stream is still good. It does not go to a fail state until after
a read has failed. This code will push a garbage character onto the
end of the vector, every time.
You're right. The reading should be incorporated into
the 'while's conditional expression.

-Mike
Mar 3 '07 #9

This discussion thread is closed

Replies have been disabled for this discussion.