Yes stringstreams are still terribly slow (at least on gcc).
Did a little benchmark comparing strtod and ostringstream.
Again if you can live with the overhead, it is the cleanest way to do string conversions (I use streams a lot but on some places going back to oldschool C-style atoi, strtod etc. is necessary)
This is copied from my page
stringstream benchtest
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 :
1. The cstreams implementation is almost 5 times faster than cppstreams
2. 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:
wschrep@pascal:~/cpp-work/streambench.cpp> ls
cppstreams.cpp cppstreams.out cstreams.cpp cstreams.out Makefile
wschrep@pascal:~/cpp-work/streambench.cpp> cat 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;
}
wschrep@pascal:~/cpp-work/streambench.cpp> cat 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;
}
wschrep@pascal:~/cpp-work/streambench.cpp> cat 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
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