From 99c5f8e00bea1b46e907ee099cc25964279f7db0 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 7 Sep 2013 12:37:18 -0700 Subject: [PATCH] Move the benchmarks to format-benchmark. --- .gitmodules | 6 +- CMakeLists.txt | 10 - format-benchmark | 2 +- tests/high_resolution_timer.hpp | 474 -------------------------------- tests/int_generator.cpp | 151 ---------- 5 files changed, 4 insertions(+), 639 deletions(-) delete mode 100644 tests/high_resolution_timer.hpp delete mode 100644 tests/int_generator.cpp diff --git a/.gitmodules b/.gitmodules index a9faa202..9ee193ce 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,9 @@ [submodule "gtest"] path = gtest url = git://github.com/vitaut/gtest.git -[submodule "tinyformat"] - path = tinyformat - url = git://github.com/vitaut/tinyformat.git +[submodule "format-benchmark"] + path = format-benchmark + url = git://github.com/vitaut/format-benchmark.git [submodule "breathe"] path = breathe url = git://github.com/vitaut/breathe.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 5022d35d..fc0a0762 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,16 +40,6 @@ if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/gtest/CMakeLists.txt) add_test(format_test format_test) endif () -find_package(Boost) -if (Boost_FOUND) - add_executable(int_generator tests/int_generator.cpp) - target_link_libraries(int_generator format) - find_library(HAVE_RT rt) - if (HAVE_RT) - target_link_libraries(int_generator rt) - endif () - add_definitions(-DHAVE_BOOST) -endif () if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/tinyformat/tinyformat_test.cpp) add_executable(tinyformat_speed_test tinyformat/tinyformat_test.cpp) diff --git a/format-benchmark b/format-benchmark index 1199f860..2f0edb47 160000 --- a/format-benchmark +++ b/format-benchmark @@ -1 +1 @@ -Subproject commit 1199f860acc7d813487e4325a858f224b2a07c49 +Subproject commit 2f0edb472bb4b5e1eea691afe3323509845346f6 diff --git a/tests/high_resolution_timer.hpp b/tests/high_resolution_timer.hpp deleted file mode 100644 index 16e926d5..00000000 --- a/tests/high_resolution_timer.hpp +++ /dev/null @@ -1,474 +0,0 @@ -// Copyright (c) 2005-2010 Hartmut Kaiser -// Copyright (c) 2009 Edward Grace -// -// 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) - -#if !defined(HIGH_RESOLUTION_TIMER_MAR_24_2008_1222PM) -#define HIGH_RESOLUTION_TIMER_MAR_24_2008_1222PM - -#include -#include - -#if defined(BOOST_HAS_UNISTD_H) -#include -#endif -#include - -#if defined(BOOST_WINDOWS) - -#include -#include -#include - -namespace util -{ - /////////////////////////////////////////////////////////////////////////////// - // - // high_resolution_timer - // A timer object measures elapsed time. - // CAUTION: Windows only! - // - /////////////////////////////////////////////////////////////////////////////// - class high_resolution_timer - { - public: - high_resolution_timer() - { - restart(); - } - - high_resolution_timer(double t) - { - LARGE_INTEGER frequency; - if (!QueryPerformanceFrequency(&frequency)) - boost::throw_exception(std::runtime_error("Couldn't acquire frequency")); - - start_time.QuadPart = (LONGLONG)(t * frequency.QuadPart); - } - - high_resolution_timer(high_resolution_timer const& rhs) - : start_time(rhs.start_time) - { - } - - static double now() - { - SYSTEMTIME st; - GetSystemTime(&st); - - FILETIME ft; - SystemTimeToFileTime(&st, &ft); - - LARGE_INTEGER now; - now.LowPart = ft.dwLowDateTime; - now.HighPart = ft.dwHighDateTime; - - // FileTime is in 100ns increments, result needs to be in [s] - return now.QuadPart * 1e-7; - } - - void restart() - { - if (!QueryPerformanceCounter(&start_time)) - boost::throw_exception(std::runtime_error("Couldn't initialize start_time")); - } - double elapsed() const // return elapsed time in seconds - { - LARGE_INTEGER now; - if (!QueryPerformanceCounter(&now)) - boost::throw_exception(std::runtime_error("Couldn't get current time")); - - LARGE_INTEGER frequency; - if (!QueryPerformanceFrequency(&frequency)) - boost::throw_exception(std::runtime_error("Couldn't acquire frequency")); - - return double(now.QuadPart - start_time.QuadPart) / frequency.QuadPart; - } - - double elapsed_max() const // return estimated maximum value for elapsed() - { - LARGE_INTEGER frequency; - if (!QueryPerformanceFrequency(&frequency)) - boost::throw_exception(std::runtime_error("Couldn't acquire frequency")); - - return double((std::numeric_limits::max)() - start_time.QuadPart) / - double(frequency.QuadPart); - } - - double elapsed_min() const // return minimum value for elapsed() - { - LARGE_INTEGER frequency; - if (!QueryPerformanceFrequency(&frequency)) - boost::throw_exception(std::runtime_error("Couldn't acquire frequency")); - - return 1.0 / frequency.QuadPart; - } - - private: - LARGE_INTEGER start_time; - }; - -} // namespace util - -#elif defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(_POSIX_THREAD_CPUTIME) - -#if _POSIX_THREAD_CPUTIME > 0 // timer always supported - -namespace util -{ - - /////////////////////////////////////////////////////////////////////////////// - // - // high_resolution_timer - // A timer object measures elapsed time. - // - /////////////////////////////////////////////////////////////////////////////// - class high_resolution_timer - { - public: - high_resolution_timer() - { - start_time.tv_sec = 0; - start_time.tv_nsec = 0; - - restart(); - } - - high_resolution_timer(double t) - { - start_time.tv_sec = time_t(t); - start_time.tv_nsec = (t - start_time.tv_sec) * 1e9; - } - - high_resolution_timer(high_resolution_timer const& rhs) - : start_time(rhs.start_time) - { - } - - static double now() - { - timespec now; - if (-1 == clock_gettime(CLOCK_REALTIME, &now)) - boost::throw_exception(std::runtime_error("Couldn't get current time")); - return double(now.tv_sec) + double(now.tv_nsec) * 1e-9; - } - - void restart() - { - if (-1 == clock_gettime(CLOCK_REALTIME, &start_time)) - boost::throw_exception(std::runtime_error("Couldn't initialize start_time")); - } - double elapsed() const // return elapsed time in seconds - { - timespec now; - if (-1 == clock_gettime(CLOCK_REALTIME, &now)) - boost::throw_exception(std::runtime_error("Couldn't get current time")); - - if (now.tv_sec == start_time.tv_sec) - return double(now.tv_nsec - start_time.tv_nsec) * 1e-9; - - return double(now.tv_sec - start_time.tv_sec) + - (double(now.tv_nsec - start_time.tv_nsec) * 1e-9); - } - - double elapsed_max() const // return estimated maximum value for elapsed() - { - return double((std::numeric_limits::max)() - start_time.tv_sec); - } - - double elapsed_min() const // return minimum value for elapsed() - { - timespec resolution; - if (-1 == clock_getres(CLOCK_REALTIME, &resolution)) - boost::throw_exception(std::runtime_error("Couldn't get resolution")); - return double(resolution.tv_sec + resolution.tv_nsec * 1e-9); - } - - private: - timespec start_time; - }; - -} // namespace util - -#else // _POSIX_THREAD_CPUTIME > 0 - -#include - -// availability of high performance timers must be checked at runtime -namespace util -{ - /////////////////////////////////////////////////////////////////////////////// - // - // high_resolution_timer - // A timer object measures elapsed time. - // - /////////////////////////////////////////////////////////////////////////////// - class high_resolution_timer - { - public: - high_resolution_timer() - : use_backup(sysconf(_SC_THREAD_CPUTIME) <= 0) - { - if (!use_backup) { - start_time.tv_sec = 0; - start_time.tv_nsec = 0; - } - restart(); - } - - high_resolution_timer(double t) - : use_backup(sysconf(_SC_THREAD_CPUTIME) <= 0) - { - if (!use_backup) { - start_time.tv_sec = time_t(t); - start_time.tv_nsec = (t - start_time.tv_sec) * 1e9; - } - } - - high_resolution_timer(high_resolution_timer const& rhs) - : use_backup(sysconf(_SC_THREAD_CPUTIME) <= 0), - start_time(rhs.start_time) - { - } - - static double now() - { - if (sysconf(_SC_THREAD_CPUTIME) <= 0) - return double(std::clock()); - - timespec now; - if (-1 == clock_gettime(CLOCK_REALTIME, &now)) - boost::throw_exception(std::runtime_error("Couldn't get current time")); - return double(now.tv_sec) + double(now.tv_nsec) * 1e-9; - } - - void restart() - { - if (use_backup) - start_time_backup.restart(); - else if (-1 == clock_gettime(CLOCK_REALTIME, &start_time)) - boost::throw_exception(std::runtime_error("Couldn't initialize start_time")); - } - double elapsed() const // return elapsed time in seconds - { - if (use_backup) - return start_time_backup.elapsed(); - - timespec now; - if (-1 == clock_gettime(CLOCK_REALTIME, &now)) - boost::throw_exception(std::runtime_error("Couldn't get current time")); - - if (now.tv_sec == start_time.tv_sec) - return double(now.tv_nsec - start_time.tv_nsec) * 1e-9; - - return double(now.tv_sec - start_time.tv_sec) + - (double(now.tv_nsec - start_time.tv_nsec) * 1e-9); - } - - double elapsed_max() const // return estimated maximum value for elapsed() - { - if (use_backup) - start_time_backup.elapsed_max(); - - return double((std::numeric_limits::max)() - start_time.tv_sec); - } - - double elapsed_min() const // return minimum value for elapsed() - { - if (use_backup) - start_time_backup.elapsed_min(); - - timespec resolution; - if (-1 == clock_getres(CLOCK_REALTIME, &resolution)) - boost::throw_exception(std::runtime_error("Couldn't get resolution")); - return double(resolution.tv_sec + resolution.tv_nsec * 1e-9); - } - - private: - bool use_backup; - timespec start_time; - boost::timer start_time_backup; - }; - -} // namespace util - -#endif // _POSIX_THREAD_CPUTIME > 0 - -#else // !defined(BOOST_WINDOWS) && (!defined(_POSIX_TIMERS) - // || _POSIX_TIMERS <= 0 - // || !defined(_POSIX_THREAD_CPUTIME) - // || _POSIX_THREAD_CPUTIME <= 0) - -#if defined(BOOST_HAS_GETTIMEOFDAY) - -// For platforms that do not support _POSIX_TIMERS but do have -// GETTIMEOFDAY, which is still preferable to std::clock() -#include -#include -#include - -namespace util -{ - - /////////////////////////////////////////////////////////////////////////// - // - // high_resolution_timer - // A timer object measures elapsed time. - // - // Implemented with gettimeofday() for platforms that support it, - // such as Darwin (OS X) but do not support the previous options. - // - // Copyright (c) 2009 Edward Grace - // - /////////////////////////////////////////////////////////////////////////// - class high_resolution_timer - { - private: - template - static inline double unsigned_diff(const U &a, const U &b) - { - if (a > b) - return static_cast(a-b); - return -static_cast(b-a); - } - - // @brief Return the difference between two timeval types. - // - // @param t1 The most recent timeval. - // @param t0 The historical timeval. - // - // @return The difference between the two in seconds. - double elapsed(const timeval &t1, const timeval &t0) const - { - if (t1.tv_sec == t0.tv_sec) - return unsigned_diff(t1.tv_usec,t0.tv_usec) * 1e-6; - - // We do it this way as the result of the difference of the - // microseconds can be negative if the clock is implemented so - // that the seconds timer increases in large steps. - // - // Naive subtraction of the unsigned types and conversion to - // double can wreak havoc! - return unsigned_diff(t1.tv_sec,t0.tv_sec) + - unsigned_diff(t1.tv_usec,t0.tv_usec) * 1e-6; - } - - public: - high_resolution_timer() - { - start_time.tv_sec = 0; - start_time.tv_usec = 0; - - restart(); - } - - high_resolution_timer(double t) - { - start_time.tv_sec = time_t(t); - start_time.tv_usec = (t - start_time.tv_sec) * 1e6; - } - - high_resolution_timer(high_resolution_timer const& rhs) - : start_time(rhs.start_time) - { - } - - static double now() - { - // Under some implementations gettimeofday() will always - // return zero. If it returns anything else however then - // we accept this as evidence of an error. Note we are - // not assuming that -1 explicitly indicates the error - // condition, just that non zero is indicative of the - // error. - timeval now; - if (gettimeofday(&now, NULL)) - boost::throw_exception(std::runtime_error("Couldn't get current time")); - return double(now.tv_sec) + double(now.tv_usec) * 1e-6; - } - - void restart() - { - if (gettimeofday(&start_time, NULL)) - boost::throw_exception(std::runtime_error("Couldn't initialize start_time")); - } - - double elapsed() const // return elapsed time in seconds - { - timeval now; - if (gettimeofday(&now, NULL)) - boost::throw_exception(std::runtime_error("Couldn't get current time")); - return elapsed(now,start_time); - } - - double elapsed_max() const // return estimated maximum value for elapsed() - { - return double((std::numeric_limits::max)() - start_time.tv_sec); - } - - double elapsed_min() const // return minimum value for elapsed() - { - // On systems without an explicit clock_getres or similar - // we can only estimate an upper bound on the resolution - // by repeatedly calling the gettimeofday function. This - // is often likely to be indicative of the true - // resolution. - timeval t0, t1; - double delta(0); - - if (gettimeofday(&t0, NULL)) - boost::throw_exception(std::runtime_error("Couldn't get resolution.")); - - // Spin around in a tight loop until we observe a change - // in the reported timer value. - do { - if (gettimeofday(&t1, NULL)) - boost::throw_exception(std::runtime_error("Couldn't get resolution.")); - delta = elapsed(t1, t0); - } while (delta <= 0.0); - - return delta; - } - - private: - timeval start_time; - }; - -} - -#else // BOOST_HAS_GETTIMEOFDAY - -// For platforms other than Windows or Linux, or not implementing gettimeofday -// simply fall back to boost::timer -#include - -namespace util -{ - struct high_resolution_timer - : boost::timer - { - static double now() - { - return double(std::clock()); - } - }; -} - -#endif - -#endif - -#endif // HIGH_RESOLUTION_TIMER_AUG_14_2009_0425PM - -// -// $Log: high_resolution_timer.hpp,v $ -// Revision 1.4 2009/08/14 15:28:10 graceej -// * It is entirely possible for the updating clock to increment the -// * seconds and *decrement* the microseconds field. Consequently -// * when subtracting these unsigned microseconds fields a wrap-around -// * error can occur. For this reason elapsed(t1, t0) is used in a -// * similar maner to cycle.h this preserves the sign of the -// * difference. -// - diff --git a/tests/int_generator.cpp b/tests/int_generator.cpp deleted file mode 100644 index 78689c68..00000000 --- a/tests/int_generator.cpp +++ /dev/null @@ -1,151 +0,0 @@ -// 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 -#include - -#include -#include -#include - -#include "high_resolution_timer.hpp" - -#include "../format.h" - -// 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 - -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 v (MAX_ITERATION); - std::generate(v.begin(), v.end(), random_fill()); // randomly fill the vector - - // test the C libraries sprintf function (the most low level function for - // string conversion available) - { - //[karma_int_performance_sprintf - 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) - { - sprintf(buffer, "%d", v[i]); - //<- - str = buffer; // compensate for string ops in other benchmarks - //-> - } - //] - - cout << "sprintf:\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_boost - 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; - } - - // test the format library - { - std::string str; - util::high_resolution_timer t; - - //[karma_int_performance_format - fmt::Writer writer; - for (int i = 0; i < MAX_ITERATION; ++i) - { - writer.Clear(); - writer << v[i]; - //<- - str = writer.c_str(); // compensate for string ops in other benchmarks - //-> - } - //] - - cout << "format:\t\t" << t.elapsed() << " [s]" << flush << endl; - } - - return 0; -} -