diff options
Diffstat (limited to 'src/boost/libs/spirit/workbench/karma')
6 files changed, 661 insertions, 0 deletions
diff --git a/src/boost/libs/spirit/workbench/karma/Jamfile b/src/boost/libs/spirit/workbench/karma/Jamfile new file mode 100644 index 00000000..e837c6d6 --- /dev/null +++ b/src/boost/libs/spirit/workbench/karma/Jamfile @@ -0,0 +1,15 @@ +#============================================================================== +# Copyright (c) 2001-2010 Joel de Guzman +# Copyright (c) 2001-2010 Hartmut Kaiser +# +# 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) +#============================================================================== +project spirit-karma-benchmark ; + +# performance tests +exe int_generator : int_generator.cpp ; +exe real_generator : real_generator.cpp ; +exe format_performance : format_performance.cpp ; +exe double_performance : double_performance.cpp ; +exe sequence_performance : sequence_performance.cpp ; diff --git a/src/boost/libs/spirit/workbench/karma/double_performance.cpp b/src/boost/libs/spirit/workbench/karma/double_performance.cpp new file mode 100644 index 00000000..e707c27c --- /dev/null +++ b/src/boost/libs/spirit/workbench/karma/double_performance.cpp @@ -0,0 +1,169 @@ +// Copyright (c) 2002-2010 Hartmut Kaiser +// Copyright (c) 2002-2010 Joel de Guzman +// +// 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) + +#include <boost/config/warning_disable.hpp> +#include <boost/spirit/include/karma.hpp> +#include <boost/format.hpp> + +#include <iostream> + +#include "../high_resolution_timer.hpp" + +#define NUMITERATIONS 1000000 + +/////////////////////////////////////////////////////////////////////////////// +// We generate plain floating point numbers in this test +//[karma_double_performance_definitions +using boost::spirit::karma::double_; +//] + +void format_performance_karma() +{ + using boost::spirit::karma::generate; + + //[karma_double_performance_plain + char buffer[256]; + //<- + util::high_resolution_timer t; + //-> + for (int i = 0; i < NUMITERATIONS; ++i) { + char *p = buffer; + generate(p, double_, 12345.12345); + *p = '\0'; + } + //] + + std::cout << "karma:\t\t" << t.elapsed() << std::endl; +// std::cout << buffer << std::endl; +} + +void format_performance_rule() +{ + using boost::spirit::karma::generate; + + boost::spirit::karma::rule<char*, double()> r; + + //[karma_double_performance_rule + char buffer[256]; + r %= double_; + //<- + util::high_resolution_timer t; + //-> + for (int i = 0; i < NUMITERATIONS; ++i) { + char *p = buffer; + generate(p, r, 12345.12345); + *p = '\0'; + } + //] + + std::cout << "karma (rule):\t" << t.elapsed() << std::endl; +// std::cout << buffer << std::endl; +} + +void format_performance_direct() +{ + using boost::spirit::karma::generate; + using boost::spirit::karma::real_inserter; + + //[karma_double_performance_direct + typedef real_inserter<double> inserter; + char buffer[256]; + //<- + util::high_resolution_timer t; + //-> + for (int i = 0; i < NUMITERATIONS; ++i) { + char *p = buffer; + inserter::call(p, 12345.12345); + *p = '\0'; + } + //] + + std::cout << "karma (direct):\t" << t.elapsed() << std::endl; +// std::cout << buffer << std::endl; +} + +void format_performance_string() +{ + using boost::spirit::karma::generate; + + //[karma_double_performance_string + std::string generated; + std::back_insert_iterator<std::string> sink(generated); + //<- + util::high_resolution_timer t; + //-> + for (int i = 0; i < NUMITERATIONS; ++i) { + generated.clear(); + generate(sink, double_, 12345.12345); + } + //] + + std::cout << "karma (string):\t" << t.elapsed() << std::endl; +// std::cout << generated << std::endl; +} + +// Boost.Format +void format_performance_boost_format() +{ + //[karma_double_performance_format + std::string generated; + boost::format double_format("%f"); + //<- + util::high_resolution_timer t; + //-> + for (int i = 0; i < NUMITERATIONS; ++i) + generated = boost::str(double_format % 12345.12345); + //] + + std::cout << "format:\t\t" << t.elapsed() << std::endl; +// std::cout << strm.str() << std::endl; +} + +void format_performance_sprintf() +{ + util::high_resolution_timer t; + + //[karma_double_performance_printf + char buffer[256]; + for (int i = 0; i < NUMITERATIONS; ++i) { + sprintf(buffer, "%f", 12345.12345); + } + //] + + std::cout << "sprintf:\t" << t.elapsed() << std::endl; +// std::cout << buffer << std::endl; +} + +void format_performance_iostreams() +{ + //[karma_double_performance_iostreams + std::stringstream strm; + //<- + util::high_resolution_timer t; + //-> + for (int i = 0; i < NUMITERATIONS; ++i) { + strm.str(""); + strm << 12345.12345; + } + //] + + std::cout << "iostreams:\t" << t.elapsed() << std::endl; +// std::cout << strm.str() << std::endl; +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + format_performance_sprintf(); + format_performance_iostreams(); + format_performance_boost_format(); + format_performance_karma(); + format_performance_string(); + format_performance_rule(); + format_performance_direct(); + return 0; +} + diff --git a/src/boost/libs/spirit/workbench/karma/format_performance.cpp b/src/boost/libs/spirit/workbench/karma/format_performance.cpp new file mode 100644 index 00000000..ee17c681 --- /dev/null +++ b/src/boost/libs/spirit/workbench/karma/format_performance.cpp @@ -0,0 +1,172 @@ +// Copyright (c) 2002-2010 Hartmut Kaiser +// Copyright (c) 2002-2010 Joel de Guzman +// +// 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) + +#include <boost/config/warning_disable.hpp> +#include <boost/spirit/include/karma.hpp> +#include <boost/format.hpp> + +#include <iostream> + +#include "../high_resolution_timer.hpp" + +#define NUMITERATIONS 1000000 + +/////////////////////////////////////////////////////////////////////////////// +// policy for real_generator, which forces to output trailing zeros in the +// fractional part +//[karma_format_performance_definitions +template <typename T> +struct double3_policy : boost::spirit::karma::real_policies<T> +{ + // we want to generate up to 3 fractional digits + static unsigned int precision(T) { return 3; } +}; + +typedef boost::spirit::karma::real_generator<double, double3_policy<double> > + double3_type; +double3_type const double3 = double3_type(); +//] + +void format_performance_karma() +{ + using boost::spirit::karma::left_align; + using boost::spirit::karma::generate; + + //[karma_format_performance_plain + char buffer[256]; + //<- + util::high_resolution_timer t; + //-> + for (int i = 0; i < NUMITERATIONS; ++i) { + char *p = buffer; + generate(p + , '[' << left_align(14)[double3] << left_align(14)[double3] << ']' + , 12345.12345, 12345.12345); + *p = '\0'; + } + //] + + std::cout << "karma:\t\t" << t.elapsed() << std::endl; +// std::cout << buffer << std::endl; +} + +void format_performance_rule() +{ + using boost::spirit::karma::left_align; + using boost::spirit::karma::generate; + + typedef boost::fusion::vector<double, double> rtype; + boost::spirit::karma::rule<char*, rtype()> r; + + //[karma_format_performance_rule + char buffer[256]; + r %= '[' << left_align(14)[double3] << left_align(14)[double3] << ']'; + //<- + util::high_resolution_timer t; + //-> + for (int i = 0; i < NUMITERATIONS; ++i) { + char *p = buffer; + generate(p, r, 12345.12345, 12345.12345); + *p = '\0'; + } + //] + + std::cout << "karma (rule):\t" << t.elapsed() << std::endl; +// std::cout << buffer << std::endl; +} + +void format_performance_string() +{ + using boost::spirit::karma::left_align; + using boost::spirit::karma::generate; + + //[karma_format_performance_string + std::string generated; + std::back_insert_iterator<std::string> sink(generated); + //<- + util::high_resolution_timer t; + //-> + for (int i = 0; i < NUMITERATIONS; ++i) { + generated.clear(); + generate(sink + , '[' << left_align(14)[double3] << left_align(14)[double3] << ']' + , 12345.12345, 12345.12345); + } + //] + + std::cout << "karma (string):\t" << t.elapsed() << std::endl; +// std::cout << generated << std::endl; +} + +// Boost.Format +void format_performance_boost_format() +{ + //[karma_format_performance_format + std::string generated; + boost::format outformat("[%-14.3f%-14.3f]"); + //<- + util::high_resolution_timer t; + //-> + for (int i = 0; i < NUMITERATIONS; ++i) + generated = boost::str(outformat % 12345.12345 % 12345.12345); + //] + + std::cout << "format:\t\t" << t.elapsed() << std::endl; +// std::cout << strm.str() << std::endl; +} + +void format_performance_sprintf() +{ + util::high_resolution_timer t; + + //[karma_format_performance_printf + char buffer[256]; + for (int i = 0; i < NUMITERATIONS; ++i) { + sprintf(buffer, "[%-14.3f%-14.3f]", 12345.12345, 12345.12345); + } + //] + + std::cout << "sprintf:\t" << t.elapsed() << std::endl; +// std::cout << buffer << std::endl; +} + +void format_performance_iostreams() +{ + //[karma_format_performance_iostreams + std::stringstream strm; + //<- + util::high_resolution_timer t; + //-> + for (int i = 0; i < NUMITERATIONS; ++i) { + strm.str(""); + strm << '[' + << std::setiosflags(std::ios::fixed) + << std::left + << std::setprecision(3) + << std::setw(14) + << 12345.12345 + << std::setw(14) + << 12345.12345 + << ']'; + } + //] + + std::cout << "iostreams:\t" << t.elapsed() << std::endl; +// std::cout << strm.str() << std::endl; +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + format_performance_sprintf(); + format_performance_iostreams(); + format_performance_boost_format(); + format_performance_karma(); + format_performance_string(); + format_performance_rule(); + return 0; +} + diff --git a/src/boost/libs/spirit/workbench/karma/int_generator.cpp b/src/boost/libs/spirit/workbench/karma/int_generator.cpp new file mode 100644 index 00000000..7c822a2c --- /dev/null +++ b/src/boost/libs/spirit/workbench/karma/int_generator.cpp @@ -0,0 +1,129 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// +// 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) + +#include <climits> +#include <cstdlib> + +#include <iostream> +#include <sstream> +#include <boost/format.hpp> + +#include "../high_resolution_timer.hpp" + +// This value specifies, how to unroll the integer string generation loop in +// Karma. +// Set this to some integer in between 0 (no unrolling) and max expected +// integer string len (complete unrolling). If not specified, this value +// defaults to 6. +#define BOOST_KARMA_NUMERICS_LOOP_UNROLL 6 + +#include <boost/spirit/include/karma.hpp> + +using namespace std; +using namespace boost::spirit; + +#define MAX_ITERATION 10000000 + +/////////////////////////////////////////////////////////////////////////////// +struct random_fill +{ + int operator()() const + { + int scale = std::rand() / 100 + 1; + return (std::rand() * std::rand()) / scale; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + namespace karma = boost::spirit::karma; + + cout << "Converting " << MAX_ITERATION + << " randomly generated int values to strings." << flush << endl; + + std::srand(0); + std::vector<int> v (MAX_ITERATION); + std::generate(v.begin(), v.end(), random_fill()); // randomly fill the vector + + // test the C libraries ltoa function (the most low level function for + // string conversion available) + { + //[karma_int_performance_ltoa + char buffer[65]; // we don't expect more than 64 bytes to be generated here + //<- + std::string str; + util::high_resolution_timer t; + //-> + for (int i = 0; i < MAX_ITERATION; ++i) + { + ltoa(v[i], buffer, 10); + //<- + str = buffer; // compensate for string ops in other benchmarks + //-> + } + //] + + cout << "ltoa:\t\t" << t.elapsed() << " [s]" << flush << endl; + } + + // test the iostreams library + { + //[karma_int_performance_iostreams + std::stringstream str; + //<- + util::high_resolution_timer t; + //-> + for (int i = 0; i < MAX_ITERATION; ++i) + { + str.str(""); + str << v[i]; + } + //] + + cout << "iostreams:\t" << t.elapsed() << " [s]" << flush << endl; + } + + // test the Boost.Format library + { + //[karma_int_performance_format + std::string str; + boost::format int_format("%d"); + //<- + util::high_resolution_timer t; + //-> + for (int i = 0; i < MAX_ITERATION; ++i) + { + str = boost::str(int_format % v[i]); + } + //] + + cout << "Boost.Format:\t" << t.elapsed() << " [s]" << flush << endl; + } + + // test the Karma int_ generation routines + { + std::string str; + util::high_resolution_timer t; + + //[karma_int_performance_plain + char buffer[65]; // we don't expect more than 64 bytes to be generated here + for (int i = 0; i < MAX_ITERATION; ++i) + { + char *ptr = buffer; + karma::generate(ptr, int_, v[i]); + *ptr = '\0'; + //<- + str = buffer; // compensate for string ops in other benchmarks + //-> + } + //] + + cout << "int_:\t\t" << t.elapsed() << " [s]" << flush << endl; + } + + return 0; +} + diff --git a/src/boost/libs/spirit/workbench/karma/real_generator.cpp b/src/boost/libs/spirit/workbench/karma/real_generator.cpp new file mode 100644 index 00000000..43a29fde --- /dev/null +++ b/src/boost/libs/spirit/workbench/karma/real_generator.cpp @@ -0,0 +1,106 @@ +// Copyright (c) 2001-2010 Hartmut Kaiser +// +// 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) + +#include <climits> +#include <cassert> + +#include <iostream> +#include <sstream> +#include <boost/format.hpp> + +#include <boost/spirit/include/karma.hpp> + +#include "../high_resolution_timer.hpp" + +using namespace std; +using namespace boost::spirit; + +#define MAX_ITERATION 10000000 + +/////////////////////////////////////////////////////////////////////////////// +struct random_fill +{ + double operator()() const + { + double scale = std::rand() / 100 + 1; + return double(std::rand() * std::rand()) / scale; + } +}; + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + namespace karma = boost::spirit::karma; + char buffer[512]; // we don't expect more than 512 bytes to be generated + + cout << "Converting " << MAX_ITERATION + << " randomly generated double values to strings." << flush << endl; + + std::srand(0); + std::vector<double> v (MAX_ITERATION); + std::generate(v.begin(), v.end(), random_fill()); // randomly fill the vector + + // test the C libraries gcvt function (the most low level function for + // string conversion available) + { + std::string str; + util::high_resolution_timer t; + + for (int i = 0; i < MAX_ITERATION; ++i) + { + gcvt(v[i], 10, buffer); + str = buffer; // compensate for string ops in other benchmarks + } + + cout << "gcvt: " << t.elapsed() << " [s]" << flush << endl; + } + + // test the iostreams library + { + std::stringstream str; + util::high_resolution_timer t; + + for (int i = 0; i < MAX_ITERATION; ++i) + { + str.str(""); + str << v[i]; + } + + cout << "iostreams: " << t.elapsed() << " [s]" << flush << endl; + } + + // test the Boost.Format library + { + std::string str; + boost::format double_format("%f"); + util::high_resolution_timer t; + + for (int i = 0; i < MAX_ITERATION; ++i) + { + str = boost::str(double_format % v[i]); + } + + cout << "Boost.Format: " << t.elapsed() << " [s]" << flush << endl; + } + + // test the Karma double_ generation routines + { + std::string str; + util::high_resolution_timer t; + + for (int i = 0; i < MAX_ITERATION; ++i) + { + char *ptr = buffer; + karma::generate(ptr, double_, v[i]); + *ptr = '\0'; + str = buffer; // compensate for string ops in other benchmarks + } + + cout << "double_: " << t.elapsed() << " [s]" << flush << endl; + } + + return 0; +} + diff --git a/src/boost/libs/spirit/workbench/karma/sequence_performance.cpp b/src/boost/libs/spirit/workbench/karma/sequence_performance.cpp new file mode 100644 index 00000000..e54febd1 --- /dev/null +++ b/src/boost/libs/spirit/workbench/karma/sequence_performance.cpp @@ -0,0 +1,70 @@ +// Copyright (c) 2005-2010 Hartmut Kaiser +// +// 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) + +#define FUSION_MAX_TUPLE_SIZE 10 +#define USE_FUSION_VECTOR + +#include <climits> + +#include <iostream> +#include <boost/preprocessor/repeat.hpp> +#include <boost/preprocessor/inc.hpp> + +#include <boost/spirit/include/karma.hpp> + +#include "../high_resolution_timer.hpp" + +/////////////////////////////////////////////////////////////////////////////// +static char const* const literal_sequences[] = { + "", "a", "ab", "abc", "abcd", "abcde", + "abcdef", "abcdefg", "abcdefgh", "abcdefghi", "abcdefgij" +}; + +/////////////////////////////////////////////////////////////////////////////// +#define MAX_ITERATION 10000000 +#define MAX_SEQUENCE_LENGTH 9 +#define RCHAR(z, n, _) char_((char)('a' + n)) << + +#define SEQUENCE_TEST(z, N, _) \ + { \ + util::high_resolution_timer t; \ + \ + for (int i = 0; i < MAX_ITERATION; ++i) \ + { \ + char *ptr = buffer; \ + generate(ptr, BOOST_PP_REPEAT(N, RCHAR, _) char_('\0')); \ + } \ + \ + std::cout << "karma::sequence(" << BOOST_PP_INC(N) << "):\t" \ + << std::setw(9) << t.elapsed() << "\t" \ + << std::flush << std::endl; \ + \ + BOOST_ASSERT(std::string(buffer) == literal_sequences[N]); \ + } \ + /**/ + +// double elapsed = t.elapsed(); \ +// for (int i = 0; i < MAX_ITERATION; ++i) \ +// { \ +// char *ptr = buffer; \ +// generate(ptr, lit(literal_sequences[N]) << char_('\0')); \ +// } \ +// \ +// t.restart(); \ +// \ +// << std::setw(9) << elapsed << " [s]" \ + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + using namespace boost::spirit::karma; + using namespace boost::spirit::ascii; + char buffer[512]; // we don't expect more than 512 bytes to be generated here + + std::cout << "Benchmarking sequence of different length: " << std::endl; + BOOST_PP_REPEAT_FROM_TO(1, MAX_SEQUENCE_LENGTH, SEQUENCE_TEST, _); + + return 0; +} |