// -*- C++ -*- // Boost general library 'format' --------------------------- // See http://www.boost.org for updates, documentation, and revision history. // Copyright (c) 2001 Samuel Krempp // krempp@crans.ens-cachan.fr // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // several suggestions from Jens Maurer // ------------------------------------------------------------------------------ // bench_variants.cc : do the same task, with sprintf, stream, and format // and compare their times. // This benchmark is provided purely for information. // It might not even compile as-is, // or not give any sensible results. // (e.g., it expects sprintf to be POSIX compliant) // ------------------------------------------------------------------------------ #include #include #include // sprintf #include #include #include // floor #include #include #include // portable /dev/null stream equivalent, by James Kanze, http://www.gabi-soft.de class NulStreambuf : public std::streambuf { public: NulStreambuf() { setp( dummyBuffer , dummyBuffer + 64 ) ; } virtual int overflow( int c ); virtual int underflow(); private: char dummyBuffer[ 64 ] ; } ; class NulStream : public std::basic_ostream > { public: NulStream(); virtual ~NulStream(); NulStreambuf* rdbuf() { return static_cast< NulStreambuf* >( ((std::basic_ostream > *) this) -> rdbuf() ) ; } } ; //------------------------------------------------------------------------------------- // NulStream implementation NulStream::NulStream() : std::basic_ostream > (NULL) { init( new NulStreambuf ) ; } NulStream::~NulStream() { delete rdbuf() ; } int NulStreambuf::underflow(){ return std::ios::traits_type::eof(); } int NulStreambuf::overflow( int c ){ setp( dummyBuffer , dummyBuffer + 64 ) ; return (c == std::ios::traits_type::eof()) ? '\0' : c ; } // ------------------------------------------------------------------------------------- namespace benchmark { static int NTests = 300000; //static std::stringstream nullStream; static NulStream nullStream; static double tstream, tpf; //static const std::string fstring="%3$#x %1$20.10E %2$g %3$d \n"; static const std::string fstring="%3$0#6x %1$20.10E %2$g %3$0+5d \n"; static const double arg1=45.23; static const double arg2=12.34; static const int arg3=23; static const std::string res = "0x0017 4.5230000000E+01 12.34 +0023 \n"; //static const std::string res = "23.0000 4.5230000000E+01 12.34 23 \n"; void test_sprintf(); void test_nullstream(); void test_opti_nullstream(); void test_parsed_once_format(); void test_reused_format(); void test_format(); void test_try1(); void test_try2(); void test_sprintf() { using namespace std; vector bufr; bufr.reserve(4000); char *buf = &bufr[0]; // Check that sprintf is Unix98 compatible on the platform : sprintf(buf, fstring.c_str(), arg1, arg2, arg3); if( strncmp( buf, res.c_str(), res.size()) != 0 ) { cerr << endl << buf; } // time the loop : boost::timer chrono; for(int i=0; i oss; oss << boost::format(fstring) % arg1 % arg2 % arg3; boost::timer chrono; size_t dummy=0; for(int i=0; i oss; oss << boost::format(fstring) % arg1 % arg2 % arg3; oss << "blas 34567890GGGGGGGGGGGGGGGGGGGGGGGGGGGGggggggggggggggggggggggggggg " << endl; string s = oss.cur_str(); oss << s << s << s; oss.clear_buffer(); oss << s << s; s = oss.cur_str(); boost::timer chrono; size_t dummy=0; for(int i=0; i oss; { do_stream(oss); if(oss.str() != res ) { cerr << endl << oss.str() ; } } for(int i=0; i oss; //static const std::string fstring="%3$#x %1$20.10E %2$g %3$d \n"; std::ios_base::fmtflags f0 = oss.flags(), f1, f2; streamsize p0 = oss.precision(); { oss << hex << showbase; f1 = oss.flags(); oss << arg3; oss.flags(f0); oss << " " << scientific << setw(20) << setprecision(10) << uppercase; f2 = oss.flags(); oss << arg1; oss.flags(f0); oss.precision(p0); oss << " " << arg2 << " " << arg3 << " \n" ; if(oss.str() != res ) { cerr << endl << oss.str() ; } } for(int i=0; i oss; oss << boost::format(fmter) % arg1 % arg2 % arg3 ; if( oss.str() != res ) { cerr << endl << oss.str(); } // not only is the format-string parsed once, // but also the buffer of the internal stringstream is already allocated. boost::timer chrono; for(int i=0; i oss; oss << boost::format(fstring) % arg1 % arg2 % arg3; if(oss.str() != res ) { cerr << endl << oss.str(); } boost::timer chrono; boost::format fmter; for(int i=0; i oss; oss << boost::format(fstring) % arg1 % arg2 % arg3; if(oss.str() != res ) { cerr << endl << oss.str(); } boost::timer chrono; for(int i=0; i