diff --git a/performance/command_line.cpp b/performance/command_line.cpp index 7c7a5a68..bdebc7a1 100644 --- a/performance/command_line.cpp +++ b/performance/command_line.cpp @@ -34,6 +34,7 @@ bool time_safe_greta = false; bool time_posix = false; bool time_pcre = false; bool time_xpressive = false; +bool time_std = false; bool test_matches = false; bool test_code = false; @@ -55,6 +56,7 @@ double locale_boost_total = 0; double posix_total = 0; double pcre_total = 0; double xpressive_total = 0; +double std_total = 0; unsigned greta_test_count = 0; unsigned safe_greta_test_count = 0; unsigned boost_test_count = 0; @@ -62,6 +64,7 @@ unsigned locale_boost_test_count = 0; unsigned posix_test_count = 0; unsigned pcre_test_count = 0; unsigned xpressive_test_count = 0; +unsigned std_test_count = 0; int handle_argument(const std::string& what) { @@ -86,6 +89,10 @@ int handle_argument(const std::string& what) #ifdef BOOST_HAS_XPRESSIVE else if(what == "-xpressive" || what == "-dxpr") time_xpressive = true; +#endif +#ifndef BOOST_NO_0X_HDR_REGEX + else if(what == "-std") + time_std = true; #endif else if(what == "-all") { @@ -103,6 +110,9 @@ int handle_argument(const std::string& what) #endif #ifdef BOOST_HAS_XPRESSIVE time_xpressive = true; +#endif +#ifndef BOOST_NO_0X_HDR_REGEX + time_std = true; #endif } else if(what == "-test-matches") @@ -166,6 +176,9 @@ int show_usage() #endif #ifdef BOOST_HAS_XPRESSIVE " -dxpr Apply tests to dynamic xpressive library\n" +#endif +#ifndef BOOST_NO_0X_HDR_REGEX + " -std Apply tests to std::regex.\n" #endif " -all Apply tests to all libraries\n\n" " test options:\n" @@ -273,6 +286,10 @@ void output_html_results(bool show_description, const std::string& tagname) #ifdef BOOST_HAS_XPRESSIVE if(time_xpressive == true) os << "Dynamic Xpressive"; +#endif +#ifndef BOOST_NO_0X_HDR_REGEX + if(time_std == true) + os << "std::regex"; #endif os << "\n"; @@ -307,7 +324,6 @@ void output_html_results(bool show_description, const std::string& tagname) } } #endif -#if defined(BOOST_HAS_POSIX) if(time_boost == true) { print_result(os, first->boost_time, first->factor); @@ -317,7 +333,6 @@ void output_html_results(bool show_description, const std::string& tagname) ++boost_test_count; } } -#endif if(time_localised_boost == true) { print_result(os, first->localised_boost_time, first->factor); @@ -357,6 +372,17 @@ void output_html_results(bool show_description, const std::string& tagname) ++xpressive_test_count; } } +#endif +#ifndef BOOST_NO_0X_HDR_REGEX + if(time_std == true) + { + print_result(os, first->std_time, first->factor); + if(first->std_time > 0) + { + std_total += first->std_time / first->factor; + ++std_test_count; + } + } #endif os << "\n"; ++first; @@ -429,6 +455,12 @@ std::string get_averages_table() { os << "Dynamic Xpressive"; } +#endif +#ifndef BOOST_NO_0X_HDR_REGEX + if(time_std == true) + { + os << "std::regex"; + } #endif os << "\n"; @@ -446,6 +478,8 @@ std::string get_averages_table() if(time_boost == true) os << "" << (boost_total / boost_test_count) << "\n"; #endif + if(time_boost == true) + os << "" << (boost_total / boost_test_count) << "\n"; if(time_localised_boost == true) os << "" << (locale_boost_total / locale_boost_test_count) << "\n"; if(time_posix == true) @@ -457,6 +491,10 @@ std::string get_averages_table() #if defined(BOOST_HAS_XPRESSIVE) if(time_xpressive == true) os << "" << (xpressive_total / xpressive_test_count) << "\n"; +#endif +#ifndef BOOST_NO_0X_HDR_REGEX + if(time_std == true) + os << "" << (std_total / std_test_count) << "\n"; #endif os << "\n"; os << "\n"; diff --git a/performance/input.html b/performance/input.html index 9b2312b8..425dedeb 100644 --- a/performance/input.html +++ b/performance/input.html @@ -46,7 +46,7 @@

Comparison 2: Medium Sized Search

For each of the following regular expressions the time taken to find all occurrences of the expression within a medium sized English language text was - measured (the first 50K from mtent12.txt). 

+ measured (the first 50K from mtent12.txt - up to the end of Chapter 1). 

%short_twain_search%

Comparison 3: C++ Code Search

For each of the following regular expressions the time taken to find all @@ -73,3 +73,4 @@ + diff --git a/performance/main.cpp b/performance/main.cpp index 203f6bd5..3301fb59 100644 --- a/performance/main.cpp +++ b/performance/main.cpp @@ -73,6 +73,14 @@ void test_match(const std::string& re, const std::string& text, const std::strin r.xpressive_time = time; std::cout << "\txpressive regex: " << time << "s\n"; } +#endif +#ifndef BOOST_NO_0X_HDR_REGEX + if(time_std == true) + { + time = stdr::time_match(re, text, icase); + r.std_time = time; + std::cout << "\tstd::regex: " << time << "s\n"; + } #endif r.finalise(); result_list.push_back(r); @@ -134,6 +142,14 @@ void test_find_all(const std::string& re, const std::string& text, const std::st r.xpressive_time = time; std::cout << "\txpressive regex: " << time << "s\n"; } +#endif +#ifndef BOOST_NO_0X_HDR_REGEX + if(time_std == true) + { + time = stdr::time_find_all(re, text, icase); + r.std_time = time; + std::cout << "\tstd::regex: " << time << "s\n"; + } #endif r.finalise(); result_list.push_back(r); diff --git a/performance/regex_comparison.hpp b/performance/regex_comparison.hpp index 1c4cc6c2..4ed968fd 100644 --- a/performance/regex_comparison.hpp +++ b/performance/regex_comparison.hpp @@ -27,6 +27,7 @@ extern bool time_safe_greta; extern bool time_posix; extern bool time_pcre; extern bool time_xpressive; +extern bool time_std; extern bool test_matches; extern bool test_short_twain; @@ -55,6 +56,7 @@ struct results double posix_time; double pcre_time; double xpressive_time; + double std_time; double factor; std::string expression; std::string description; @@ -66,6 +68,7 @@ struct results posix_time(-1), pcre_time(-1), xpressive_time(-1), + std_time(-1), factor((std::numeric_limits::max)()), expression(ex), description(desc) @@ -86,6 +89,8 @@ struct results factor = pcre_time; if((xpressive_time >= 0) && (xpressive_time < factor)) factor = xpressive_time; + if((std_time >= 0) && (std_time < factor)) + factor = std_time; } }; @@ -133,6 +138,11 @@ namespace dxpr { double time_match(const std::string& re, const std::string& text, bool icase); double time_find_all(const std::string& re, const std::string& text, bool icase); } +namespace stdr { +// xpressive tests: +double time_match(const std::string& re, const std::string& text, bool icase); +double time_find_all(const std::string& re, const std::string& text, bool icase); +} void test_match(const std::string& re, const std::string& text, const std::string& description, bool icase = false); void test_find_all(const std::string& re, const std::string& text, const std::string& description, bool icase = false); diff --git a/performance/time_std.cpp b/performance/time_std.cpp new file mode 100644 index 00000000..46fa212b --- /dev/null +++ b/performance/time_std.cpp @@ -0,0 +1,123 @@ +/* + * + * Copyright (c) 2002 + * John Maddock + * + * Use, modification and distribution are subject to 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 "regex_comparison.hpp" +#ifndef BOOST_NO_0X_HDR_REGEX +#include +#include +#include + +namespace stdr{ + +double time_match(const std::string& re, const std::string& text, bool icase) +{ + try{ + std::regex e(re, (icase ? std::regex::ECMAScript | std::regex::icase : std::regex::ECMAScript)); + std::smatch what; + boost::timer tim; + int iter = 1; + int counter, repeats; + double result = 0; + double run; + do + { + tim.restart(); + for(counter = 0; counter < iter; ++counter) + { + std::regex_match(text, what, e); + } + result = tim.elapsed(); + iter *= 2; + }while(result < 0.5); + iter /= 2; + + // repeat test and report least value for consistency: + for(repeats = 0; repeats < REPEAT_COUNT; ++repeats) + { + tim.restart(); + for(counter = 0; counter < iter; ++counter) + { + std::regex_match(text, what, e); + } + run = tim.elapsed(); + result = (std::min)(run, result); + } + return result / iter; + } + catch(const std::exception& e) + { + std::cout << "Exception: " << e.what() << std::endl; + return -1; + } +} + +bool dummy_grep_proc(const std::smatch&) +{ return true; } + +struct noop +{ + void operator()( std::smatch const & ) const + { + } +}; + +double time_find_all(const std::string& re, const std::string& text, bool icase) +{ + try{ + std::regex e(re, (icase ? std::regex::ECMAScript | std::regex::icase : std::regex::ECMAScript)); + std::smatch what; + boost::timer tim; + int iter = 1; + int counter, repeats; + double result = 0; + double run; + do + { + tim.restart(); + for(counter = 0; counter < iter; ++counter) + { + std::sregex_iterator begin( text.begin(), text.end(), e ), end; + std::for_each( begin, end, noop() ); + //std::regex_grep(&dummy_grep_proc, text, e); + } + result = tim.elapsed(); + iter *= 2; + }while(result < 0.5); + iter /= 2; + + if(result >10) + return result / iter; + + // repeat test and report least value for consistency: + for(repeats = 0; repeats < REPEAT_COUNT; ++repeats) + { + tim.restart(); + for(counter = 0; counter < iter; ++counter) + { + std::sregex_iterator begin( text.begin(), text.end(), e ), end; + std::for_each( begin, end, noop() ); + //std::regex_grep(&dummy_grep_proc, text, e); + } + run = tim.elapsed(); + result = (std::min)(run, result); + } + return result / iter; + } + catch(const std::exception& e) + { + std::cout << "Exception: " << e.what() << std::endl; + return -1; + } +} + +} + +#endif