diff --git a/benchmark/bench_format.cpp b/benchmark/bench_format.cpp
new file mode 100644
index 0000000..393df75
--- /dev/null
+++ b/benchmark/bench_format.cpp
@@ -0,0 +1,356 @@
+// -*- 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 <iostream>
+#include <iomanip>
+#include <cstdio>  // sprintf
+#include <cstring>
+#include <fstream>
+#include <cmath>   // floor
+#include <boost/timer.hpp>
+#include <vector>
+
+#include <boost/format.hpp>
+
+// 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<char, std::char_traits<char> > 
+{
+public:
+  NulStream();
+  virtual ~NulStream();
+  NulStreambuf*    rdbuf() {
+    return static_cast< NulStreambuf* >(
+                   ((std::basic_ostream<char, std::char_traits<char> > *) this) -> rdbuf() ) ;
+  }
+} ;
+ 
+
+//-------------------------------------------------------------------------------------
+//   NulStream implementation
+
+NulStream::NulStream()  : std::basic_ostream<char, std::char_traits<char> > (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<char> 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<NTests; ++i) {
+      sprintf(buf, fstring.c_str(), arg1, arg2, arg3);
+    }
+    tpf=chrono.elapsed();
+    cout  << left << setw(20) <<"printf time"<< right <<":" << tpf  << endl;
+}
+
+void test_try1()
+{
+  using namespace std;
+  boost::io::basic_oaltstringstream<char> oss;
+  oss << boost::format(fstring) % arg1 % arg2 % arg3;
+  boost::timer chrono;
+  size_t dummy=0;
+  for(int i=0; i<NTests; ++i) {
+      dummy += oss.cur_size();
+  }
+  double t = chrono.elapsed();
+  cout  << left << setw(20) <<"try1 time"<< right <<":" << setw(5) << t
+        << ",  = " << t / tpf << " * printf "
+        << ",  = " << t / tstream << " * nullStream \n";
+}
+
+void test_try2()
+{
+  using namespace std;
+  boost::io::basic_oaltstringstream<char> 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<NTests; ++i) {
+      dummy += oss.cur_size();
+  }
+  double t = chrono.elapsed();
+  cout  << left << setw(20) <<"try2 time"<< right <<":" << setw(5) << t
+        << ",  = " << t / tpf << " * printf "
+        << ",  = " << t / tstream << " * nullStream \n";
+}
+
+void do_stream(std::ostream& os) {
+    using namespace std;
+    std::ios_base::fmtflags f = os.flags();
+    os << hex << showbase << internal << setfill('0') << setw(6) << arg3
+       << dec << noshowbase << right << setfill(' ') 
+       << " " 
+       << scientific << setw(20) << setprecision(10) << uppercase << arg1 
+       << setprecision(6) << nouppercase ;
+    os.flags(f);
+    os << " " << arg2 << " " 
+       << showpos << setw(5) << internal << setfill('0') << arg3 << " \n" ;
+    os.flags(f);
+}
+
+void test_nullstream()
+{
+    using namespace std;
+    boost::timer chrono;
+    boost::io::basic_oaltstringstream<char> oss;
+
+    {   
+        do_stream(oss);
+        if(oss.str() != res ) {
+            cerr << endl << oss.str() ;
+        }
+    }
+
+    for(int i=0; i<NTests; ++i) { 
+        do_stream(nullStream);
+    }
+
+//     for(int i=0; i<NTests; ++i) { 
+//       std::ios_base::fmtflags f0 = nullStream.flags();
+//       nullStream << hex << showbase << arg3
+//                  << dec << noshowbase << " " 
+//                  << scientific << setw(20) << setprecision(10) << uppercase <<  arg1 
+//                  << setprecision(0);
+//       nullStream.flags(f0);
+//       nullStream << " " << arg2 << " " << arg3 << " \n" ;
+
+//     }
+    double t = chrono.elapsed();
+    cout  << left << setw(20) <<"ostream time"<< right <<":" << setw(5) << t  
+          << ",  = " << t / tpf << " * printf \n";
+    tstream = t;
+}
+
+void test_opti_nullstream()
+{
+    using namespace std;
+    boost::timer chrono;
+    boost::io::basic_oaltstringstream<char> 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<NTests; ++i) { 
+      nullStream.flags(f1);
+      nullStream << arg3;
+
+      nullStream << setw(20) << setprecision(10);
+      nullStream.flags(f2);
+      nullStream << arg1;
+
+      nullStream.flags(f0); nullStream.precision(p0);
+      nullStream << " " << arg2 << " " << arg3 << " \n" ;
+    }
+    double t = chrono.elapsed();
+    cout  << left << setw(20) <<"opti-stream time"<< right <<":" << setw(5) << t  
+          << ",  = " << t / tpf << " * printf \n";
+    //    tstream = t;
+}
+
+void test_parsed_once_format()
+{
+    using namespace std;
+    static const boost::format fmter(fstring);
+
+    boost::io::basic_oaltstringstream<char> 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<NTests; ++i) {
+        nullStream << boost::format(fmter) % arg1 % arg2 % arg3;
+    }
+    double t=chrono.elapsed();
+    cout  << left << setw(20) <<"parsed-once time"<< right <<":" << setw(5) << t 
+          << ",  = " << t / tpf << " * printf "
+          << ",  = " << t / tstream << " * nullStream \n";
+}
+
+void test_reused_format()
+{
+  using namespace std;
+  boost::io::basic_oaltstringstream<char> 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<NTests; ++i) {
+    nullStream << fmter.parse(fstring) % arg1 % arg2 % arg3;
+  }
+  double t = chrono.elapsed();
+  cout  << left << setw(20) <<"reused format time"<< right <<":" << setw(5) << t
+        << ",  = " << t / tpf << " * printf "
+        << ",  = " << t / tstream << " * nullStream \n";
+}
+
+void test_format()
+{
+  using namespace std;
+  boost::io::basic_oaltstringstream<char> oss;
+  oss << boost::format(fstring) % arg1 % arg2 % arg3;
+  if(oss.str() != res ) {
+    cerr << endl << oss.str();
+  }
+
+  boost::timer chrono;
+  for(int i=0; i<NTests; ++i) {
+    nullStream << boost::format(fstring) % arg1 % arg2 % arg3;
+  }
+  double t = chrono.elapsed();
+  cout  << left << setw(20) <<"format time"<< right <<":" << setw(5) << t
+        << ",  = " << t / tpf << " * printf "
+        << ",  = " << t / tstream << " * nullStream \n";
+}
+
+} // benchmark
+
+int main(int argc, char * argv[]) {
+    using namespace benchmark;
+    using namespace boost;
+    using namespace std;
+    const string::size_type  npos = string::npos;
+
+    string choices = "";
+    if (1<argc) {
+        choices = (argv[1]); // profiling is easier launching only one.
+        NTests = 1000 * 1000;  // andmoreprecise with many iterations
+        cout << "choices (" << choices << ") \n";
+    }
+
+    if (choices == "" || choices.find('p') != npos)
+        test_sprintf();
+    if (choices == "" || choices.find('n') != npos)
+        test_nullstream();
+    if (choices == "" || choices.find('1') != npos)
+        test_parsed_once_format();
+    if (choices == "" || choices.find('r') != npos)
+        test_reused_format();
+    if (choices == "" || choices.find('f') != npos)
+        test_format();
+    if (choices.find('t') != npos)
+        test_try1();
+    if (choices.find('y') != npos)
+        test_try2();
+    if (choices.find('o') != npos)
+        test_opti_nullstream();
+    return 0;
+}
+
