C++ streams (with gcc) still too slow and bugs?!
Written by Walter on x/x/2004
Why are cpp sstream's still so slow and maybe also contain a conversion bug?
Here follows a simple example (okay did not try to optimize anything here, just used sstream in a classroom type example and compared it to the c-style sprintf and strtod functions).
What we notice is :
- The cstreams implementation is almost 5 times faster than cppstreams
- The cppstreams gives an extra double which differs from original after conversion to string and back. The differences between value and repVal are normal/understandable but it's not logical why the cpp stringstreams have one more difference between value/repVal than when using srtod+sprintf...
Here are my files and a testrun:
cppstreams.cpp
#include <iostream>
#include <sstream>
using namespace std;
int main(){
double value = 1.0;
double repVal= 0;
for( int i=0;i<100000;i++){
value = (value/2)+1;
//double to string
ostringstream os;
os << value << endl;
string strVal = os.str();
//string to double
istringstream is( strVal );
is >> repVal;
if( repVal != value ){
cout << "repVal = "<<repVal<<" != value =" << value <<endl;
}
}
cout << "done!"<<endl;
return 0;
}
cstreams.cpp:
#include <iostream>
#include <sstream>
using namespace std;
#include <stdio.h>
#include <stdlib.h>
int main(){
double value = 1.0;
double repVal= 0;
for( int i=0;i<100000;i++){
value = (value/2)+1;
//double to string
char cp[255];
sprintf( cp, "%f", value );
string strVal( cp );
//string to double
char * pEnd;
repVal = strtod( strVal.c_str(), &pEnd );
if( repVal != value ){
cout << "repVal = "<<repVal<<" != value =" << value <<endl;
}
}
cout << "done!"<<endl;
return 0;
}
Makefile
INCLUDE = -I.
CXX = g++
CXXFLAGS = -O2 -Wall $(INCLUDE)
all: cppstreams cstreams
cppstreams: cppstreams.o
$(CXX) $(CXXFLAGS) -o cppstreams cppstreams.o
cstreams: cstreams.o
$(CXX) $(CXXFLAGS) -o cstreams cstreams.o
clean:
@rm -vf *.o *~ DEADJOE cppstreams cstreams
Now compile and benchmark run:
wschrep@pascal:~/cpp-work/streambench.cpp> make
g++ -O2 -Wall -I. -c -o cppstreams.o cppstreams.cpp
g++ -O2 -Wall -I. -o cppstreams cppstreams.o
g++ -O2 -Wall -I. -c -o cstreams.o cstreams.cpp
g++ -O2 -Wall -I. -o cstreams cstreams.o
wschrep@pascal:~/cpp-work/streambench.cpp> time ./cppstreams > cppstreams.out
real 0m1.558s
user 0m1.557s
sys 0m0.001s
wschrep@pascal:~/cpp-work/streambench.cpp> time ./cstreams > cstreams.out
real 0m0.334s
user 0m0.331s
sys 0m0.002s
wschrep@pascal:~/cpp-work/streambench.cpp> diff cstreams.out cppstreams.out
0a1
> repVal = 1.98438 != value =1.98438
So wassup here dudes? Don't have time to find a mailing list to post this so I'm just gonna put it here in my DIY blog :)
Incidently I was benching these 2 methods of conversion for my matrix class which will have to do such conversions from string to double and other types when parsing scripts and interpreting them... For now I'm probably going to write a little wrapper class around the c-style conversion I guess... since it gives such a speed improvement ;)