Change docs to use new performance test code,

upgrade docs to quickbook 1.7.
This commit is contained in:
jzmaddock
2015-10-15 13:27:45 +01:00
parent 3939d1a1a4
commit 76ce33da74
60 changed files with 3098 additions and 3913 deletions

View File

@ -1,56 +1,71 @@
# copyright John Maddock 2003
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# Copyright Daryle Walker, Hubert Holin, John Maddock 2006 - 2007
# copyright Paul A. Bristow 2006 - 2010
# 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.
# \math_toolkit\libs\math\test\jamfile.v2
# Runs all math toolkit tests, functions & distributions,
# and build math examples.
SOURCES = command_line main time_boost time_greta time_localised_boost time_pcre time_dynamic_xpressive time_posix time_safe_greta ;
# bring in the rules for testing
import testing ;
import modules ;
import path ;
import pch ;
using quickbook ;
using auto-index ;
local HS_REGEX_PATH = [ modules.peek : HS_REGEX_PATH ] ;
local USE_POSIX = [ modules.peek : USE_POSIX ] ;
local PCRE_PATH = [ modules.peek : PCRE_PATH ] ;
local USE_PCRE = [ modules.peek : USE_PCRE ] ;
path-constant images_location : html ;
path-constant here : . ;
if $(HS_REGEX_PATH)
{
HS_SOURCES = $(HS_REGEX_PATH)/regcomp.c $(HS_REGEX_PATH)/regerror.c $(HS_REGEX_PATH)/regexec.c $(HS_REGEX_PATH)/regfree.c ;
POSIX_OPTS = <define>BOOST_HAS_POSIX=1 <include>$(HS_REGEX_PATH) ;
}
else if $(USE_POSIX)
{
POSIX_OPTS = <define>BOOST_HAS_POSIX=1 ;
}
lib pcre2 ;
lib regex ;
lib re2 ;
lib pcre : : <name>pcre ;
exe has_pcre2 : config/pcre.cpp pcre2 : <include>third_party <dll-path>third_party <library-path>third_party release ;
explicit has_pcre2 ;
exe has_posix : config/posix.cpp : release <source>regex ;
explicit has_posix ;
exe has_re2 : config/re2.cpp : release <source>re2 <include>third_party <dll-path>third_party <library-path>third_party ;
explicit has_re2 ;
if $(PCRE_PATH)
{
PCRE_SOURCES = $(PCRE_PATH)/chartables.c $(PCRE_PATH)/get.c $(PCRE_PATH)/pcre.c $(PCRE_PATH)/study.c ;
PCRE_OPTS = <define>BOOST_HAS_PCRE=1 <include>$(PCRE_PATH) ;
}
else if $(USE_PCRE)
{
PCRE_OPTS = <define>BOOST_HAS_PCRE=1 ;
PCRE_SOURCES = pcre ;
}
run [ glob *.cpp ] /boost/regex//boost_regex /boost/system /boost/chrono /boost/filesystem
: : :
release
[ check-target-builds has_pcre2 : <define>TEST_PCRE2 <source>pcre2 ]
[ check-target-builds has_posix : <define>TEST_POSIX <source>regex ]
[ check-target-builds has_re2 : <define>TEST_RE2 <source>re2 <include>third_party <dll-path>third_party <library-path>third_party ]
<include>third_party
<dll-path>third_party
<library-path>third_party
: performance ;
exe regex_comparison :
$(SOURCES).cpp
$(HS_SOURCES)
$(PCRE_SOURCES)
../build//boost_regex
../../test/build//boost_prg_exec_monitor/<link>static
:
<define>BOOST_REGEX_NO_LIB=1
<define>BOOST_REGEX_STATIC_LINK=1
$(POSIX_OPTS)
$(PCRE_OPTS)
xml report : doc/report.qbk : <dependency>performance ;
boostbook standalone
:
report
:
# Path for links to Boost:
<xsl:param>boost.root=../../../..
# Some general style settings:
<xsl:param>table.footnote.number.format=1
<xsl:param>footnote.number.format=1
<xsl:param>html.stylesheet=../../../../doc/src/boostbook.css
# HTML options first:
# Use graphics not text for navigation:
<xsl:param>navig.graphics=1
# How far down we chunk nested sections, basically all of them:
<xsl:param>chunk.section.depth=0
# Don't put the first section on the same page as the TOC:
<xsl:param>chunk.first.sections=0
# How far down sections get TOC's
<xsl:param>toc.section.depth=2
# Max depth in each TOC:
<xsl:param>toc.max.depth=4
# How far down we go with TOC's
<xsl:param>generate.section.toc.level=10
;
install . : regex_comparison ;

62
performance/boost.cpp Normal file
View File

@ -0,0 +1,62 @@
///////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. 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_
//
#include "performance.hpp"
#include <boost/regex.hpp>
#include <boost/version.hpp>
#include <boost/lexical_cast.hpp>
struct boost_regex : public abstract_regex
{
private:
boost::regex e;
boost::cmatch what;
public:
virtual bool set_expression(const char* pe, bool isperl)
{
e.assign(pe, isperl ? boost::regex::perl : boost::regex::extended);
return e.status() == 0;
}
virtual bool match_test(const char* text);
virtual unsigned find_all(const char* text);
virtual std::string name();
struct initializer
{
initializer()
{
boost_regex::register_instance(boost::shared_ptr<abstract_regex>(new boost_regex));
}
void do_nothing()const {}
};
static const initializer init;
};
const boost_regex::initializer boost_regex::init;
bool boost_regex::match_test(const char * text)
{
return regex_match(text, what, e);
}
unsigned boost_regex::find_all(const char * text)
{
boost::regex_iterator<const char*> i(text, text + std::strlen(text), e), j;
unsigned count = 0;
while(i != j)
{
++i;
++count;
}
return count;
}
std::string boost_regex::name()
{
init.do_nothing();
return boost_name();
}

View File

@ -1,556 +0,0 @@
/*
*
* Copyright (c) 2002-2003
* 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 <iostream>
#include <iomanip>
#include <fstream>
#include <deque>
#include <sstream>
#include <stdexcept>
#include <iterator>
#include <boost/regex.hpp>
#include <boost/version.hpp>
#include "regex_comparison.hpp"
#ifdef BOOST_HAS_PCRE
#include "pcre.h" // for pcre version number
#endif
//
// globals:
//
bool time_boost = false;
bool time_localised_boost = false;
bool time_greta = false;
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;
bool test_html = false;
bool test_short_twain = false;
bool test_long_twain = false;
std::string html_template_file;
std::string html_out_file;
std::string html_contents;
std::list<results> result_list;
// the following let us compute averages:
double greta_total = 0;
double safe_greta_total = 0;
double boost_total = 0;
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;
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)
{
if(what == "-b")
time_boost = true;
else if(what == "-bl")
time_localised_boost = true;
#ifdef BOOST_HAS_GRETA
else if(what == "-g")
time_greta = true;
else if(what == "-gs")
time_safe_greta = true;
#endif
#ifdef BOOST_HAS_POSIX
else if(what == "-posix")
time_posix = true;
#endif
#ifdef BOOST_HAS_PCRE
else if(what == "-pcre")
time_pcre = true;
#endif
#ifdef BOOST_HAS_XPRESSIVE
else if(what == "-xpressive" || what == "-dxpr")
time_xpressive = true;
#endif
#ifndef BOOST_NO_CXX11_HDR_REGEX
else if(what == "-std")
time_std = true;
#endif
else if(what == "-all")
{
time_boost = true;
time_localised_boost = true;
#ifdef BOOST_HAS_GRETA
time_greta = true;
time_safe_greta = true;
#endif
#ifdef BOOST_HAS_POSIX
time_posix = true;
#endif
#ifdef BOOST_HAS_PCRE
time_pcre = true;
#endif
#ifdef BOOST_HAS_XPRESSIVE
time_xpressive = true;
#endif
#ifndef BOOST_NO_CXX11_HDR_REGEX
time_std = true;
#endif
}
else if(what == "-test-matches")
test_matches = true;
else if(what == "-test-code")
test_code = true;
else if(what == "-test-html")
test_html = true;
else if(what == "-test-short-twain")
test_short_twain = true;
else if(what == "-test-long-twain")
test_long_twain = true;
else if(what == "-test-all")
{
test_matches = true;
test_code = true;
test_html = true;
test_short_twain = true;
test_long_twain = true;
}
else if((what == "-h") || (what == "--help"))
return show_usage();
else if((what[0] == '-') || (what[0] == '/'))
{
std::cerr << "Unknown argument: \"" << what << "\"" << std::endl;
return 1;
}
else if(html_template_file.size() == 0)
{
html_template_file = what;
load_file(html_contents, what.c_str());
}
else if(html_out_file.size() == 0)
html_out_file = what;
else
{
std::cerr << "Unexpected argument: \"" << what << "\"" << std::endl;
return 1;
}
return 0;
}
int show_usage()
{
std::cout <<
"Usage\n"
"regex_comparison [-h] [library options] [test options] [html_template html_output_file]\n"
" -h Show help\n\n"
" library options:\n"
" -b Apply tests to boost library\n"
" -bl Apply tests to boost library with C++ locale\n"
#ifdef BOOST_HAS_GRETA
" -g Apply tests to GRETA library\n"
" -gs Apply tests to GRETA library (in non-recursive mode)\n"
#endif
#ifdef BOOST_HAS_POSIX
" -posix Apply tests to POSIX library\n"
#endif
#ifdef BOOST_HAS_PCRE
" -pcre Apply tests to PCRE library\n"
#endif
#ifdef BOOST_HAS_XPRESSIVE
" -dxpr Apply tests to dynamic xpressive library\n"
#endif
#ifndef BOOST_NO_CXX11_HDR_REGEX
" -std Apply tests to std::regex.\n"
#endif
" -all Apply tests to all libraries\n\n"
" test options:\n"
" -test-matches Test short matches\n"
" -test-code Test c++ code examples\n"
" -test-html Test c++ code examples\n"
" -test-short-twain Test short searches\n"
" -test-long-twain Test long searches\n"
" -test-all Test everthing\n";
return 1;
}
void load_file(std::string& text, const char* file)
{
std::deque<char> temp_copy;
std::ifstream is(file);
if(!is.good())
{
std::string msg("Unable to open file: \"");
msg.append(file);
msg.append("\"");
throw std::runtime_error(msg);
}
is.seekg(0, std::ios_base::end);
std::istream::pos_type pos = is.tellg();
is.seekg(0, std::ios_base::beg);
text.erase();
text.reserve(pos);
std::istreambuf_iterator<char> it(is);
std::copy(it, std::istreambuf_iterator<char>(), std::back_inserter(text));
}
void print_result(std::ostream& os, double time, double best)
{
static const char* suffixes[] = {"s", "ms", "us", "ns", "ps", };
if(time < 0)
{
os << "<td>NA</td>";
return;
}
double rel = time / best;
bool highlight = ((rel > 0) && (rel < 1.1));
unsigned suffix = 0;
while(time < 0)
{
time *= 1000;
++suffix;
}
os << "<td>";
if(highlight)
os << "<font color=\"#008000\">";
if(rel <= 1000)
os << std::setprecision(3) << rel;
else
os << (int)rel;
os << "<BR>(";
if(time <= 1000)
os << std::setprecision(3) << time;
else
os << (int)time;
os << suffixes[suffix] << ")";
if(highlight)
os << "</font>";
os << "</td>";
}
std::string html_quote(const std::string& in)
{
static const boost::regex e("(<)|(>)|(&)|(\")");
static const std::string format("(?1&lt;)(?2&gt;)(?3&amp;)(?4&quot;)");
return regex_replace(in, e, format, boost::match_default | boost::format_all);
}
void output_html_results(bool show_description, const std::string& tagname)
{
std::stringstream os;
if(result_list.size())
{
//
// start by outputting the table header:
//
os << "<table border=\"1\" cellspacing=\"1\">\n";
os << "<tr><td><strong>Expression</strong></td>";
if(show_description)
os << "<td><strong>Text</strong></td>";
#if defined(BOOST_HAS_GRETA)
if(time_greta == true)
os << "<td><strong>GRETA</strong></td>";
if(time_safe_greta == true)
os << "<td><strong>GRETA<BR>(non-recursive mode)</strong></td>";
#endif
if(time_boost == true)
os << "<td><strong>Boost</strong></td>";
if(time_localised_boost == true)
os << "<td><strong>Boost + C++ locale</strong></td>";
#if defined(BOOST_HAS_POSIX)
if(time_posix == true)
os << "<td><strong>POSIX</strong></td>";
#endif
#ifdef BOOST_HAS_PCRE
if(time_pcre == true)
os << "<td><strong>PCRE</strong></td>";
#endif
#ifdef BOOST_HAS_XPRESSIVE
if(time_xpressive == true)
os << "<td><strong>Dynamic Xpressive</strong></td>";
#endif
#ifndef BOOST_NO_CXX11_HDR_REGEX
if(time_std == true)
os << "<td><strong>std::regex</strong></td>";
#endif
os << "</tr>\n";
//
// Now enumerate through all the test results:
//
std::list<results>::const_iterator first, last;
first = result_list.begin();
last = result_list.end();
while(first != last)
{
os << "<tr><td><code>" << html_quote(first->expression) << "</code></td>";
if(show_description)
os << "<td>" << html_quote(first->description) << "</td>";
#if defined(BOOST_HAS_GRETA)
if(time_greta == true)
{
print_result(os, first->greta_time, first->factor);
if(first->greta_time > 0)
{
greta_total += first->greta_time / first->factor;
++greta_test_count;
}
}
if(time_safe_greta == true)
{
print_result(os, first->safe_greta_time, first->factor);
if(first->safe_greta_time > 0)
{
safe_greta_total += first->safe_greta_time / first->factor;
++safe_greta_test_count;
}
}
#endif
if(time_boost == true)
{
print_result(os, first->boost_time, first->factor);
if(first->boost_time > 0)
{
boost_total += first->boost_time / first->factor;
++boost_test_count;
}
}
if(time_localised_boost == true)
{
print_result(os, first->localised_boost_time, first->factor);
if(first->localised_boost_time > 0)
{
locale_boost_total += first->localised_boost_time / first->factor;
++locale_boost_test_count;
}
}
if(time_posix == true)
{
print_result(os, first->posix_time, first->factor);
if(first->posix_time > 0)
{
posix_total += first->posix_time / first->factor;
++posix_test_count;
}
}
#if defined(BOOST_HAS_PCRE)
if(time_pcre == true)
{
print_result(os, first->pcre_time, first->factor);
if(first->pcre_time > 0)
{
pcre_total += first->pcre_time / first->factor;
++pcre_test_count;
}
}
#endif
#if defined(BOOST_HAS_XPRESSIVE)
if(time_xpressive == true)
{
print_result(os, first->xpressive_time, first->factor);
if(first->xpressive_time > 0)
{
xpressive_total += first->xpressive_time / first->factor;
++xpressive_test_count;
}
}
#endif
#ifndef BOOST_NO_CXX11_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 << "</tr>\n";
++first;
}
os << "</table>\n";
result_list.clear();
}
else
{
os << "<P><I>Results not available...</I></P>\n";
}
std::string result = os.str();
std::string::size_type pos = html_contents.find(tagname);
if(pos != std::string::npos)
{
html_contents.replace(pos, tagname.size(), result);
}
}
std::string get_boost_version()
{
std::stringstream os;
os << (BOOST_VERSION / 100000) << '.' << ((BOOST_VERSION / 100) % 1000) << '.' << (BOOST_VERSION % 100);
return os.str();
}
std::string get_averages_table()
{
std::stringstream os;
//
// start by outputting the table header:
//
os << "<table border=\"1\" cellspacing=\"1\">\n";
os << "<tr>";
#if defined(BOOST_HAS_GRETA)
if(time_greta == true)
{
os << "<td><strong>GRETA</strong></td>";
}
if(time_safe_greta == true)
{
os << "<td><strong>GRETA<BR>(non-recursive mode)</strong></td>";
}
#endif
if(time_boost == true)
{
os << "<td><strong>Boost</strong></td>";
}
if(time_localised_boost == true)
{
os << "<td><strong>Boost + C++ locale</strong></td>";
}
#if defined(BOOST_HAS_POSIX)
if(time_posix == true)
{
os << "<td><strong>POSIX</strong></td>";
}
#endif
#ifdef BOOST_HAS_PCRE
if(time_pcre == true)
{
os << "<td><strong>PCRE</strong></td>";
}
#endif
#ifdef BOOST_HAS_XPRESSIVE
if(time_xpressive == true)
{
os << "<td><strong>Dynamic Xpressive</strong></td>";
}
#endif
#ifndef BOOST_NO_CXX11_HDR_REGEX
if(time_std == true)
{
os << "<td><strong>std::regex</strong></td>";
}
#endif
os << "</tr>\n";
//
// Now enumerate through all averages:
//
os << "<tr>";
#if defined(BOOST_HAS_GRETA)
if(time_greta == true)
os << "<td>" << (greta_total / greta_test_count) << "</td>\n";
if(time_safe_greta == true)
os << "<td>" << (safe_greta_total / safe_greta_test_count) << "</td>\n";
#endif
#if defined(BOOST_HAS_POSIX)
if(time_boost == true)
os << "<td>" << (boost_total / boost_test_count) << "</td>\n";
#endif
if(time_boost == true)
os << "<td>" << (boost_total / boost_test_count) << "</td>\n";
if(time_localised_boost == true)
os << "<td>" << (locale_boost_total / locale_boost_test_count) << "</td>\n";
if(time_posix == true)
os << "<td>" << (posix_total / posix_test_count) << "</td>\n";
#if defined(BOOST_HAS_PCRE)
if(time_pcre == true)
os << "<td>" << (pcre_total / pcre_test_count) << "</td>\n";
#endif
#if defined(BOOST_HAS_XPRESSIVE)
if(time_xpressive == true)
os << "<td>" << (xpressive_total / xpressive_test_count) << "</td>\n";
#endif
#ifndef BOOST_NO_CXX11_HDR_REGEX
if(time_std == true)
os << "<td>" << (std_total / std_test_count) << "</td>\n";
#endif
os << "</tr>\n";
os << "</table>\n";
return os.str();
}
void output_final_html()
{
if(html_out_file.size())
{
//
// start with search and replace ops:
//
std::string::size_type pos;
pos = html_contents.find("%compiler%");
if(pos != std::string::npos)
{
html_contents.replace(pos, 10, BOOST_COMPILER);
}
pos = html_contents.find("%library%");
if(pos != std::string::npos)
{
html_contents.replace(pos, 9, BOOST_STDLIB);
}
pos = html_contents.find("%os%");
if(pos != std::string::npos)
{
html_contents.replace(pos, 4, BOOST_PLATFORM);
}
pos = html_contents.find("%boost%");
if(pos != std::string::npos)
{
html_contents.replace(pos, 7, get_boost_version());
}
pos = html_contents.find("%pcre%");
if(pos != std::string::npos)
{
#ifdef PCRE_MINOR
html_contents.replace(pos, 6, BOOST_STRINGIZE(PCRE_MAJOR.PCRE_MINOR));
#else
html_contents.replace(pos, 6, "N/A");
#endif
}
pos = html_contents.find("%averages%");
if(pos != std::string::npos)
{
html_contents.replace(pos, 10, get_averages_table());
}
//
// now right the output to file:
//
std::ofstream os(html_out_file.c_str());
os << html_contents;
}
else
{
std::cout << html_contents;
}
}

View File

@ -0,0 +1,17 @@
///////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. 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_
//
#define PCRE2_STATIC
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
int main()
{
pcre2_match_data* pdata = pcre2_match_data_create(30, NULL);
pcre2_match_data_free(pdata);
return 0;
}

View File

@ -0,0 +1,15 @@
///////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. 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_
//
#include <regex.h>
int main()
{
regex_t pe;
int r = regcomp(&pe, "foo", REG_EXTENDED);
regfree(&pe);
return r;
}

View File

@ -0,0 +1,12 @@
///////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. 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_
//
#include <re2.h>
int main()
{
return re2::RE2::FullMatch("a", "a") ? 0 : 1;
}

View File

@ -0,0 +1,112 @@
[/tables:]
[template table_Testing_Perl_searches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_[]
[table:table_Testing_Perl_searches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_ Testing Perl searches (platform = Windows x64, compiler = Microsoft Visual C++ version 14.0)
[[Expression[br]Text][boost 1.60][PCRE-10.10][RE2][std::regex][boost::xpressive::cregex]]
[[[^(?i)<a\u005B\^>\u005D+href\=("\u005B\^"\u005D\*"|\u005B\^\u005B:space:\u005D\u005D+)\u005B\^>\u005D\*>][br]In file: ../../../libs/libraries.htm][[role blue 1.26[br](320274ns)]][[role green 1.00[br](253424ns)]][[role blue 1.45[br](366324ns)]][[role grey -]][[role blue 3.00[br](759495ns)]]]
[[[^(?i)<font\u005B\^>\u005D+face\=("\u005B\^"\u005D\*"|\u005B\^\u005B:space:\u005D\u005D+)\u005B\^>\u005D\*>.\*?<\/font>][br]In file: ../../../libs/libraries.htm][[role blue 2.94[br](198426ns)]][[role blue 1.28[br](86670ns)]][[role green 1.00[br](67463ns)]][[role grey -]][[role blue 2.92[br](197323ns)]]]
[[[^(?i)<h\u005B12345678\u005D\u005B\^>\u005D\*>.\*?<\/h\u005B12345678\u005D>][br]In file: ../../../libs/libraries.htm][[role blue 2.42[br](196304ns)]][[role blue 1.26[br](102129ns)]][[role green 1.00[br](81160ns)]][[role grey -]][[role red 5.12[br](415932ns)]]]
[[[^(?i)<img\u005B\^>\u005D+src\=("\u005B\^"\u005D\*"|\u005B\^\u005B:space:\u005D\u005D+)\u005B\^>\u005D\*>][br]In file: ../../../libs/libraries.htm][[role blue 2.87[br](196348ns)]][[role blue 1.28[br](87365ns)]][[role green 1.00[br](68502ns)]][[role grey -]][[role blue 3.25[br](222612ns)]]]
[[[^(?i)<p>.\*?<\/p>][br]In file: ../../../libs/libraries.htm][[role blue 2.78[br](194346ns)]][[role blue 1.27[br](88709ns)]][[role green 1.00[br](70020ns)]][[role grey -]][[role red 4.03[br](282425ns)]]]
[[[^(\\w+)\\s\*(\\(\u005B\^()\u005D++(?:(?2)\u005B\^()\u005D++)\*+\u005B\^)\u005D\*\\))\\s\*(\\{\u005B\^{}\u005D++((?3)\u005B\^{}\u005D++)\*+\u005B\^}\u005D\*+\\})][br]In file: boost/multiprecision/number.hpp][[role green 1.00[br](1094575ns)]][[role blue 2.87[br](3136734ns)]][[role grey -]][[role grey -]][[role grey -]]]
[[[^(\^\u005B \\t\u005D\*\#(?:(?>\u005B\^\\\\\\n\u005D+)|\\\\(?>\\s\*\\n|.))\*)|][br]In file: boost/multiprecision/number.hpp][[role blue 1.92[br](11651545ns)]][[role green 1.00[br](6057879ns)]][[role grey -]][[role grey -]][[role blue 1.55[br](9388319ns)]]]
[[[^(template\u005B\u005B:space:\u005D\u005D\*<\u005B\^;:{\u005D+>\u005B\u005B:space:\u005D\u005D\*)?(class|struct)\u005B\u005B:space:\u005D\u005D\*(\\w+(\u005B \u005D\*\\(\u005B\^)\u005D\*\\))?\u005B\u0 ...][br]In file: boost/multiprecision/number.hpp][[role red 29.23[br](8736875ns)]][[role red 38.71[br](11569512ns)]][[role green 1.00[br](298862ns)]][[role red 995.92[br](297642713ns)]][[role red 27.63[br](8258368ns)]]]
[[[^Beman|John|Dave][br]In file: ../../../libs/libraries.htm][[role blue 1.60[br](153603ns)]][[role green 1.10[br](105220ns)]][[role blue 2.55[br](244839ns)]][[role red 8.53[br](819095ns)]][[role green 1.00[br](96081ns)]]]
[[[^\\w+\\s\*(\\(\u005B\^()\u005D++(?:(?1)\u005B\^()\u005D++)\*+\u005B\^)\u005D\*\\))][br]In file: boost/multiprecision/number.hpp][[role green 1.00[br](1099128ns)]][[role blue 1.66[br](1824126ns)]][[role grey -]][[role grey -]][[role grey -]]]
[[[^\\{\u005B\^{}\u005D++((?0)\u005B\^{}\u005D++)\*+\u005B\^}\u005D\*+\\}][br]In file: boost/multiprecision/number.hpp][[role blue 1.60[br](243611ns)]][[role green 1.00[br](152166ns)]][[role grey -]][[role grey -]][[role grey -]]]
[[[^\^\u005B \u005D\*\#\u005B \u005D\*include\u005B \u005D+("\u005B\^"\u005D+"|<\u005B\^>\u005D+>)][br]In file: boost/multiprecision/number.hpp][[role blue 1.54[br](260929ns)]][[role green 1.18[br](198707ns)]][[role blue 1.81[br](305923ns)]][[role red 8.53[br](1440180ns)]][[role green 1.00[br](168902ns)]]]
[[[^\^\u005B \u005D\*\#\u005B \u005D\*include\u005B \u005D+("boost\/\u005B\^"\u005D+"|<boost\/\u005B\^>\u005D+>)][br]In file: boost/multiprecision/number.hpp][[role blue 1.52[br](256685ns)]][[role green 1.17[br](198358ns)]][[role blue 1.80[br](303602ns)]][[role red 8.51[br](1438197ns)]][[role green 1.00[br](168968ns)]]]
]
]
[template table_Testing_leftmost_longest_searches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_[]
[table:table_Testing_leftmost_longest_searches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_ Testing leftmost-longest searches (platform = Windows x64, compiler = Microsoft Visual C++ version 14.0)
[[Expression[br]Text][boost 1.60][std::regex]]
[[[^<a\u005B\^>\u005D+href\=("\u005B\^"\u005D\*"|\u005B\^\u005B:space:\u005D\u005D+)\u005B\^>\u005D\*>][br]In file: ../../../libs/libraries.htm][[role green 1.00[br](1518659ns)]][[role red 7.17[br](10890189ns)]]]
[[[^<img\u005B\^>\u005D+src\=("\u005B\^"\u005D\*"|\u005B\^\u005B:space:\u005D\u005D+)\u005B\^>\u005D\*>][br]In file: ../../../libs/libraries.htm][[role green 1.00[br](185869ns)]][[role blue 3.77[br](700484ns)]]]
[[[^Beman|John|Dave][br]In file: ../../../libs/libraries.htm][[role green 1.00[br](165840ns)]][[role red 4.95[br](820933ns)]]]
]
]
[template table_Testing_simple_Perl_matches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_[]
[table:table_Testing_simple_Perl_matches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_ Testing simple Perl matches (platform = Windows x64, compiler = Microsoft Visual C++ version 14.0)
[[Expression[br]Text][boost 1.60][PCRE-10.10][RE2][std::regex][boost::xpressive::cregex]]
[[[^(\u005B\u005B:digit:\u005D\u005D{4}\u005B- \u005D){3}\u005B\u005B:digit:\u005D\u005D{3,4}][br][^1234-5678-1234-456]][[role blue 2.03[br](323ns)]][[role blue 1.25[br](198ns)]][[role green 1.00[br](159ns)]][[role red 20.73[br](3296ns)]][[role blue 1.38[br](220ns)]]]
[[[^\^(\u005B0-9\u005D+)(\\-| |\$)(.\*)\$][br][^100- this is a line of ftp response which contains a message string]][[role blue 1.71[br](257ns)]][[role blue 2.01[br](302ns)]][[role blue 2.38[br](357ns)]][[role red 30.81[br](4622ns)]][[role green 1.00[br](150ns)]]]
[[[^\^(\u005Ba-zA-Z0-9\_\\-\\.\u005D+)\@((\\\u005B\u005B0-9\u005D{1,3}\\.\u005B0-9\u005D{1,3}\\.\u005B0-9\u005D{1,3}\\.)|((\u005Ba-zA-Z0-9\\-\u005D+\\.)+))(\u005Ba-zA-Z\u005D{2,4}|\u005B0-9\u005D{1,3})(\\ ...][br][^bob.smith\@foo.tv]][[role blue 2.66[br](404ns)]][[role blue 2.09[br](317ns)]][[role green 1.00[br](152ns)]][[role red 38.14[br](5798ns)]][[role blue 1.87[br](284ns)]]]
[[[^\^(\u005Ba-zA-Z0-9\_\\-\\.\u005D+)\@((\\\u005B\u005B0-9\u005D{1,3}\\.\u005B0-9\u005D{1,3}\\.\u005B0-9\u005D{1,3}\\.)|((\u005Ba-zA-Z0-9\\-\u005D+\\.)+))(\u005Ba-zA-Z\u005D{2,4}|\u005B0-9\u005D{1,3})(\\ ...][br][^foo12\@foo.edu]][[role blue 2.90[br](406ns)]][[role blue 2.31[br](323ns)]][[role green 1.00[br](140ns)]][[role red 41.41[br](5797ns)]][[role blue 2.00[br](280ns)]]]
[[[^\^(\u005Ba-zA-Z0-9\_\\-\\.\u005D+)\@((\\\u005B\u005B0-9\u005D{1,3}\\.\u005B0-9\u005D{1,3}\\.\u005B0-9\u005D{1,3}\\.)|((\u005Ba-zA-Z0-9\\-\u005D+\\.)+))(\u005Ba-zA-Z\u005D{2,4}|\u005B0-9\u005D{1,3})(\\ ...][br][^john\@johnmaddock.co.uk]][[role blue 2.74[br](477ns)]][[role blue 2.17[br](378ns)]][[role green 1.00[br](174ns)]][[role red 38.15[br](6638ns)]][[role blue 2.20[br](382ns)]]]
[[[^\^\u005B-+\u005D?\u005B\u005B:digit:\u005D\u005D\*\\.?\u005B\u005B:digit:\u005D\u005D\*\$][br][^+3.14159]][[role blue 1.63[br](171ns)]][[role green 1.14[br](120ns)]][[role green 1.13[br](119ns)]][[role red 34.15[br](3586ns)]][[role green 1.00[br](105ns)]]]
[[[^\^\u005B-+\u005D?\u005B\u005B:digit:\u005D\u005D\*\\.?\u005B\u005B:digit:\u005D\u005D\*\$][br][^-3.14159]][[role blue 1.69[br](171ns)]][[role green 1.18[br](119ns)]][[role green 1.18[br](119ns)]][[role red 35.54[br](3590ns)]][[role green 1.00[br](101ns)]]]
[[[^\^\u005B-+\u005D?\u005B\u005B:digit:\u005D\u005D\*\\.?\u005B\u005B:digit:\u005D\u005D\*\$][br][^123]][[role blue 1.60[br](149ns)]][[role green 1.15[br](107ns)]][[role green 1.10[br](102ns)]][[role red 39.99[br](3719ns)]][[role green 1.00[br](93ns)]]]
[[[^\^\u005B\u005B:digit:\u005D\u005D{1,2}\/\u005B\u005B:digit:\u005D\u005D{1,2}\/\u005B\u005B:digit:\u005D\u005D{4}\$][br][^12\/12\/2001]][[role blue 1.65[br](162ns)]][[role green 1.00[br](98ns)]][[role blue 1.31[br](128ns)]][[role red 16.57[br](1624ns)]][[role green 1.03[br](101ns)]]]
[[[^\^\u005B\u005B:digit:\u005D\u005D{1,2}\/\u005B\u005B:digit:\u005D\u005D{1,2}\/\u005B\u005B:digit:\u005D\u005D{4}\$][br][^4\/1\/2001]][[role blue 1.58[br](153ns)]][[role green 1.00[br](97ns)]][[role green 1.19[br](115ns)]][[role red 16.54[br](1604ns)]][[role green 1.02[br](99ns)]]]
[[[^\^\u005Ba-zA-Z\u005D{1,2}\u005B0-9\u005D\u005B0-9A-Za-z\u005D{0,1} {0,1}\u005B0-9\u005D\u005BA-Za-z\u005D{2}\$][br][^EH10 2QQ]][[role blue 1.57[br](170ns)]][[role green 1.00[br](108ns)]][[role green 1.10[br](119ns)]][[role red 21.83[br](2358ns)]][[role green 1.00[br](108ns)]]]
[[[^\^\u005Ba-zA-Z\u005D{1,2}\u005B0-9\u005D\u005B0-9A-Za-z\u005D{0,1} {0,1}\u005B0-9\u005D\u005BA-Za-z\u005D{2}\$][br][^G1 1AA]][[role blue 1.50[br](159ns)]][[role green 1.01[br](107ns)]][[role green 1.05[br](111ns)]][[role red 17.67[br](1873ns)]][[role green 1.00[br](106ns)]]]
[[[^\^\u005Ba-zA-Z\u005D{1,2}\u005B0-9\u005D\u005B0-9A-Za-z\u005D{0,1} {0,1}\u005B0-9\u005D\u005BA-Za-z\u005D{2}\$][br][^SW1 1ZZ]][[role blue 1.53[br](164ns)]][[role green 1.00[br](107ns)]][[role green 1.07[br](115ns)]][[role red 18.05[br](1931ns)]][[role green 1.00[br](107ns)]]]
[[[^abc][br][^abc]][[role blue 2.10[br](128ns)]][[role green 1.00[br](61ns)]][[role blue 1.30[br](79ns)]][[role red 9.89[br](603ns)]][[role blue 1.25[br](76ns)]]]
]
]
[template table_Testing_simple_leftmost_longest_matches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_[]
[table:table_Testing_simple_leftmost_longest_matches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_ Testing simple leftmost-longest matches (platform = Windows x64, compiler = Microsoft Visual C++ version 14.0)
[[Expression[br]Text][boost 1.60][std::regex]]
[[[^(\u005B\u005B:digit:\u005D\u005D{4}\u005B- \u005D){3}\u005B\u005B:digit:\u005D\u005D{3,4}][br][^1234-5678-1234-456]][[role green 1.00[br](490ns)]][[role red 6.88[br](3372ns)]]]
[[[^\^(\u005B0-9\u005D+)(\\-| |\$)(.\*)\$][br][^100- this is a line of ftp response which contains a message string]][[role green 1.00[br](554ns)]][[role grey -]]]
[[[^\^(\u005Ba-zA-Z0-9\_\\-\\.\u005D+)\@((\\\u005B\u005B0-9\u005D{1,3}\\.\u005B0-9\u005D{1,3}\\.\u005B0-9\u005D{1,3}\\.)|((\u005Ba-zA-Z0-9\\-\u005D+\\.)+))(\u005Ba-zA-Z\u005D{2,4}|\u005B0-9\u005D{1,3})(\\ ...][br][^bob.smith\@foo.tv]][[role green 1.00[br](614ns)]][[role grey -]]]
[[[^\^(\u005Ba-zA-Z0-9\_\\-\\.\u005D+)\@((\\\u005B\u005B0-9\u005D{1,3}\\.\u005B0-9\u005D{1,3}\\.\u005B0-9\u005D{1,3}\\.)|((\u005Ba-zA-Z0-9\\-\u005D+\\.)+))(\u005Ba-zA-Z\u005D{2,4}|\u005B0-9\u005D{1,3})(\\ ...][br][^foo12\@foo.edu]][[role green 1.00[br](596ns)]][[role grey -]]]
[[[^\^(\u005Ba-zA-Z0-9\_\\-\\.\u005D+)\@((\\\u005B\u005B0-9\u005D{1,3}\\.\u005B0-9\u005D{1,3}\\.\u005B0-9\u005D{1,3}\\.)|((\u005Ba-zA-Z0-9\\-\u005D+\\.)+))(\u005Ba-zA-Z\u005D{2,4}|\u005B0-9\u005D{1,3})(\\ ...][br][^john\@johnmaddock.co.uk]][[role green 1.00[br](748ns)]][[role grey -]]]
[[[^\^\u005B-+\u005D?\u005B\u005B:digit:\u005D\u005D\*\\.?\u005B\u005B:digit:\u005D\u005D\*\$][br][^+3.14159]][[role green 1.00[br](372ns)]][[role red 9.77[br](3635ns)]]]
[[[^\^\u005B-+\u005D?\u005B\u005B:digit:\u005D\u005D\*\\.?\u005B\u005B:digit:\u005D\u005D\*\$][br][^-3.14159]][[role green 1.00[br](367ns)]][[role red 9.84[br](3613ns)]]]
[[[^\^\u005B-+\u005D?\u005B\u005B:digit:\u005D\u005D\*\\.?\u005B\u005B:digit:\u005D\u005D\*\$][br][^123]][[role green 1.00[br](444ns)]][[role red 8.45[br](3754ns)]]]
[[[^\^\u005B\u005B:digit:\u005D\u005D{1,2}\/\u005B\u005B:digit:\u005D\u005D{1,2}\/\u005B\u005B:digit:\u005D\u005D{4}\$][br][^12\/12\/2001]][[role green 1.00[br](325ns)]][[role red 5.19[br](1687ns)]]]
[[[^\^\u005B\u005B:digit:\u005D\u005D{1,2}\/\u005B\u005B:digit:\u005D\u005D{1,2}\/\u005B\u005B:digit:\u005D\u005D{4}\$][br][^4\/1\/2001]][[role green 1.00[br](308ns)]][[role red 5.39[br](1660ns)]]]
[[[^\^\u005Ba-zA-Z\u005D{1,2}\u005B0-9\u005D\u005B0-9A-Za-z\u005D{0,1} {0,1}\u005B0-9\u005D\u005BA-Za-z\u005D{2}\$][br][^EH10 2QQ]][[role green 1.00[br](356ns)]][[role red 6.78[br](2415ns)]]]
[[[^\^\u005Ba-zA-Z\u005D{1,2}\u005B0-9\u005D\u005B0-9A-Za-z\u005D{0,1} {0,1}\u005B0-9\u005D\u005BA-Za-z\u005D{2}\$][br][^G1 1AA]][[role green 1.00[br](315ns)]][[role red 6.14[br](1935ns)]]]
[[[^\^\u005Ba-zA-Z\u005D{1,2}\u005B0-9\u005D\u005B0-9A-Za-z\u005D{0,1} {0,1}\u005B0-9\u005D\u005BA-Za-z\u005D{2}\$][br][^SW1 1ZZ]][[role green 1.00[br](346ns)]][[role red 5.68[br](1967ns)]]]
[[[^abc][br][^abc]][[role green 1.00[br](287ns)]][[role blue 2.32[br](667ns)]]]
]
]
[/sections:]
[template section_Testing_Perl_searches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_[]
[section:section_Testing_Perl_searches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_ Testing Perl searches (platform = Windows x64, compiler = Microsoft Visual C++ version 14.0)]
[table_Testing_Perl_searches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_]
[endsect]
]
[template section_Testing_leftmost_longest_searches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_[]
[section:section_Testing_leftmost_longest_searches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_ Testing leftmost-longest searches (platform = Windows x64, compiler = Microsoft Visual C++ version 14.0)]
[table_Testing_leftmost_longest_searches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_]
[endsect]
]
[template section_Testing_simple_Perl_matches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_[]
[section:section_Testing_simple_Perl_matches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_ Testing simple Perl matches (platform = Windows x64, compiler = Microsoft Visual C++ version 14.0)]
[table_Testing_simple_Perl_matches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_]
[endsect]
]
[template section_Testing_simple_leftmost_longest_matches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_[]
[section:section_Testing_simple_leftmost_longest_matches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_ Testing simple leftmost-longest matches (platform = Windows x64, compiler = Microsoft Visual C++ version 14.0)]
[table_Testing_simple_leftmost_longest_matches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_]
[endsect]
]
[template performance_all_sections[]
[section_Testing_Perl_searches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_]
[section_Testing_leftmost_longest_searches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_]
[section_Testing_simple_Perl_matches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_]
[section_Testing_simple_leftmost_longest_matches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_]
]
[template performance_all_tables[]
[table_Testing_Perl_searches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_]
[table_Testing_leftmost_longest_searches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_]
[table_Testing_simple_Perl_matches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_]
[table_Testing_simple_leftmost_longest_matches_platform_Windows_x64_compiler_Microsoft_Visual_C_version_14_0_]
]

View File

@ -0,0 +1,20 @@
[article Boost.Regex Performance Report
[quickbook 1.6]
[/purpose ISBN 0-9504833-2-X 978-0-9504833-2-0, Classification 519.2-dc22]
[license
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])
]
]
[import performance_tables.qbk]
[performance_all_sections]
[/
Copyright 2015 John Maddock and Paul A. Bristow.
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).
]

View File

@ -1,76 +0,0 @@
<html>
<head>
<title>Regular Expression Performance Comparison</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
<meta name="Template" content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
<!-- boostinspect:nounlinked -->
</head>
<body bgcolor="#ffffff" link="#0000ff" vlink="#800080">
<h2>Regular Expression Performance Comparison</h2>
<p>
The following tables provide comparisons between the following regular
expression libraries:</p>
<p><a href="http://research.microsoft.com/projects/greta">GRETA</a>.</p>
<p><a href="http://www.boost.org/">The Boost regex library</a>.</p>
<p><a href="http://arglist.com/regex/">Henry Spencer's regular expression library</a>
- this is provided for comparison as a typical non-backtracking implementation.</p>
<P>Philip Hazel's <A href="http://www.pcre.org">PCRE</A> library.</P>
<H3>Details</H3>
<P>Machine: Intel Pentium 4 2.8GHz PC.</P>
<P>Compiler: %compiler%.</P>
<P>C++ Standard Library: %library%.</P>
<P>OS: %os%.</P>
<P>Boost version: %boost%.</P>
<P>PCRE version: %pcre%.</P>
<P>
As ever care should be taken in interpreting the results, only sensible regular
expressions (rather than pathological cases) are given, most are taken from the
Boost regex examples, or from the <a href="http://www.regxlib.com/">Library of
Regular Expressions</a>. In addition, some variation in the relative
performance of these libraries can be expected on other machines - as memory
access and processor caching effects can be quite large for most finite state
machine algorithms.</P>
<H3>Averages</H3>
<P>The following are the average relative scores for all the tests: the perfect
regular expression library&nbsp;would score 1, in practice anything less than 2
is pretty good.</P>
<P>%averages%</P>
<h3>Comparison 1: Long Search</h3>
<p>For each of the following regular expressions the time taken to find all
occurrences of the expression within a long English language text was measured
(<a href="http://www.gutenberg.org/files/3200/old/mtent12.zip">mtent12.txt</a>
from <a href="http://promo.net/pg/">Project Gutenberg</a>, 19Mb).&nbsp;</p>
<P>%long_twain_search%</P>
<h3>Comparison 2: Medium Sized Search</h3>
<p>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 - up to the end of Chapter 1).&nbsp;</p>
<P>%short_twain_search%</P>
<H3>Comparison 3:&nbsp;C++ Code&nbsp;Search</H3>
<P>For each of the following regular expressions the time taken to find all
occurrences of the expression within the C++ source file <A href="../../../boost/crc.hpp">
boost/crc.hpp</A>&nbsp;was measured.&nbsp;</P>
<P>%code_search%</P>
<H3>
<H3>Comparison 4: HTML Document Search</H3>
</H3>
<P>For each of the following regular expressions the time taken to find all
occurrences of the expression within the html file <A href="../../libraries.htm">libs/libraries.htm</A>
was measured.&nbsp;</P>
<P>%html_search%</P>
<H3>Comparison 3: Simple Matches</H3>
<p>
For each of the following regular expressions the time taken to match against
the text indicated was measured.&nbsp;</p>
<P>%short_matches%</P>
<hr>
<p><i>© Copyright John Maddock&nbsp;2003</i></p>
<p><i>Use, modification and distribution are subject to the Boost Software License,
Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a>
or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
</body>
</html>

View File

@ -1,280 +0,0 @@
/*
*
* 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 <iostream>
#include <fstream>
#include <iterator>
#include <cassert>
#include <boost/test/execution_monitor.hpp>
#include "regex_comparison.hpp"
void test_match(const std::string& re, const std::string& text, const std::string& description, bool icase)
{
double time;
results r(re, description);
std::cout << "Testing: \"" << re << "\" against \"" << description << "\"" << std::endl;
#ifdef BOOST_HAS_GRETA
if(time_greta == true)
{
time = g::time_match(re, text, icase);
r.greta_time = time;
std::cout << "\tGRETA regex: " << time << "s\n";
}
if(time_safe_greta == true)
{
time = gs::time_match(re, text, icase);
r.safe_greta_time = time;
std::cout << "\tSafe GRETA regex: " << time << "s\n";
}
#endif
if(time_boost == true)
{
time = b::time_match(re, text, icase);
r.boost_time = time;
std::cout << "\tBoost regex: " << time << "s\n";
}
if(time_localised_boost == true)
{
time = bl::time_match(re, text, icase);
r.localised_boost_time = time;
std::cout << "\tBoost regex (C++ locale): " << time << "s\n";
}
#ifdef BOOST_HAS_POSIX
if(time_posix == true)
{
time = posix::time_match(re, text, icase);
r.posix_time = time;
std::cout << "\tPOSIX regex: " << time << "s\n";
}
#endif
#ifdef BOOST_HAS_PCRE
if(time_pcre == true)
{
time = pcr::time_match(re, text, icase);
r.pcre_time = time;
std::cout << "\tPCRE regex: " << time << "s\n";
}
#endif
#ifdef BOOST_HAS_XPRESSIVE
if(time_xpressive == true)
{
time = dxpr::time_match(re, text, icase);
r.xpressive_time = time;
std::cout << "\txpressive regex: " << time << "s\n";
}
#endif
#ifndef BOOST_NO_CXX11_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);
}
void test_find_all(const std::string& re, const std::string& text, const std::string& description, bool icase)
{
std::cout << "Testing: " << re << std::endl;
double time;
results r(re, description);
#ifdef BOOST_HAS_GRETA
if(time_greta == true)
{
time = g::time_find_all(re, text, icase);
r.greta_time = time;
std::cout << "\tGRETA regex: " << time << "s\n";
}
if(time_safe_greta == true)
{
time = gs::time_find_all(re, text, icase);
r.safe_greta_time = time;
std::cout << "\tSafe GRETA regex: " << time << "s\n";
}
#endif
if(time_boost == true)
{
time = b::time_find_all(re, text, icase);
r.boost_time = time;
std::cout << "\tBoost regex: " << time << "s\n";
}
if(time_localised_boost == true)
{
time = bl::time_find_all(re, text, icase);
r.localised_boost_time = time;
std::cout << "\tBoost regex (C++ locale): " << time << "s\n";
}
#ifdef BOOST_HAS_POSIX
if(time_posix == true)
{
time = posix::time_find_all(re, text, icase);
r.posix_time = time;
std::cout << "\tPOSIX regex: " << time << "s\n";
}
#endif
#ifdef BOOST_HAS_PCRE
if(time_pcre == true)
{
time = pcr::time_find_all(re, text, icase);
r.pcre_time = time;
std::cout << "\tPCRE regex: " << time << "s\n";
}
#endif
#ifdef BOOST_HAS_XPRESSIVE
if(time_xpressive == true)
{
time = dxpr::time_find_all(re, text, icase);
r.xpressive_time = time;
std::cout << "\txpressive regex: " << time << "s\n";
}
#endif
#ifndef BOOST_NO_CXX11_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);
}
int cpp_main(int argc, char * argv[])
{
// start by processing the command line args:
if(argc < 2)
return show_usage();
int result = 0;
for(int c = 1; c < argc; ++c)
{
result += handle_argument(argv[c]);
}
if(result)
return result;
if(test_matches)
{
// start with a simple test, this is basically a measure of the minimal overhead
// involved in calling a regex matcher:
test_match("abc", "abc");
// these are from the regex docs:
test_match("^([0-9]+)(\\-| |$)(.*)$", "100- this is a line of ftp response which contains a message string");
test_match("([[:digit:]]{4}[- ]){3}[[:digit:]]{3,4}", "1234-5678-1234-456");
// these are from http://www.regxlib.com/
test_match("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$", "john@johnmaddock.co.uk");
test_match("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$", "foo12@foo.edu");
test_match("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$", "bob.smith@foo.tv");
test_match("^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$", "EH10 2QQ");
test_match("^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$", "G1 1AA");
test_match("^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$", "SW1 1ZZ");
test_match("^[[:digit:]]{1,2}/[[:digit:]]{1,2}/[[:digit:]]{4}$", "4/1/2001");
test_match("^[[:digit:]]{1,2}/[[:digit:]]{1,2}/[[:digit:]]{4}$", "12/12/2001");
test_match("^[-+]?[[:digit:]]*\\.?[[:digit:]]*$", "123");
test_match("^[-+]?[[:digit:]]*\\.?[[:digit:]]*$", "+3.14159");
test_match("^[-+]?[[:digit:]]*\\.?[[:digit:]]*$", "-3.14159");
}
output_html_results(true, "%short_matches%");
std::string file_contents;
if(test_code)
{
load_file(file_contents, "../../../boost/crc.hpp");
const char* highlight_expression = // preprocessor directives: index 1
"(^[ \t]*#(?:[^\\\\\\n]|\\\\[^\\n_[:punct:][:alnum:]]*[\\n[:punct:][:word:]])*)|"
// comment: index 2
"(//[^\\n]*|/\\*.*?\\*/)|"
// literals: index 3
"\\<([+-]?(?:(?:0x[[:xdigit:]]+)|(?:(?:[[:digit:]]*\\.)?[[:digit:]]+(?:[eE][+-]?[[:digit:]]+)?))u?(?:(?:int(?:8|16|32|64))|L)?)\\>|"
// string literals: index 4
"('(?:[^\\\\']|\\\\.)*'|\"(?:[^\\\\\"]|\\\\.)*\")|"
// keywords: index 5
"\\<(__asm|__cdecl|__declspec|__export|__far16|__fastcall|__fortran|__import"
"|__pascal|__rtti|__stdcall|_asm|_cdecl|__except|_export|_far16|_fastcall"
"|__finally|_fortran|_import|_pascal|_stdcall|__thread|__try|asm|auto|bool"
"|break|case|catch|cdecl|char|class|const|const_cast|continue|default|delete"
"|do|double|dynamic_cast|else|enum|explicit|extern|false|float|for|friend|goto"
"|if|inline|int|long|mutable|namespace|new|operator|pascal|private|protected"
"|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_cast"
"|struct|switch|template|this|throw|true|try|typedef|typeid|typename|union|unsigned"
"|using|virtual|void|volatile|wchar_t|while)\\>"
;
const char* class_expression = "^(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
"(class|struct)[[:space:]]*(\\<\\w+\\>([ \t]*\\([^)]*\\))?"
"[[:space:]]*)*(\\<\\w*\\>)[[:space:]]*(<[^;:{]+>[[:space:]]*)?"
"(\\{|:[^;\\{()]*\\{)";
const char* include_expression = "^[ \t]*#[ \t]*include[ \t]+(\"[^\"]+\"|<[^>]+>)";
const char* boost_include_expression = "^[ \t]*#[ \t]*include[ \t]+(\"boost/[^\"]+\"|<boost/[^>]+>)";
test_find_all(class_expression, file_contents);
test_find_all(highlight_expression, file_contents);
test_find_all(include_expression, file_contents);
test_find_all(boost_include_expression, file_contents);
}
output_html_results(false, "%code_search%");
if(test_html)
{
load_file(file_contents, "../../../libs/libraries.htm");
test_find_all("beman|john|dave", file_contents, true);
test_find_all("<p>.*?</p>", file_contents, true);
test_find_all("<a[^>]+href=(\"[^\"]*\"|[^[:space:]]+)[^>]*>", file_contents, true);
test_find_all("<h[12345678][^>]*>.*?</h[12345678]>", file_contents, true);
test_find_all("<img[^>]+src=(\"[^\"]*\"|[^[:space:]]+)[^>]*>", file_contents, true);
test_find_all("<font[^>]+face=(\"[^\"]*\"|[^[:space:]]+)[^>]*>.*?</font>", file_contents, true);
}
output_html_results(false, "%html_search%");
if(test_short_twain)
{
load_file(file_contents, "short_twain.txt");
test_find_all("Twain", file_contents);
test_find_all("Huck[[:alpha:]]+", file_contents);
test_find_all("[[:alpha:]]+ing", file_contents);
test_find_all("^[^\n]*?Twain", file_contents);
test_find_all("Tom|Sawyer|Huckleberry|Finn", file_contents);
test_find_all("(Tom|Sawyer|Huckleberry|Finn).{0,30}river|river.{0,30}(Tom|Sawyer|Huckleberry|Finn)", file_contents);
}
output_html_results(false, "%short_twain_search%");
if(test_long_twain)
{
load_file(file_contents, "mtent13.txt");
test_find_all("Twain", file_contents);
test_find_all("Huck[[:alpha:]]+", file_contents);
test_find_all("[[:alpha:]]+ing", file_contents);
test_find_all("^[^\n]*?Twain", file_contents);
test_find_all("Tom|Sawyer|Huckleberry|Finn", file_contents);
time_posix = false;
test_find_all("(Tom|Sawyer|Huckleberry|Finn).{0,30}river|river.{0,30}(Tom|Sawyer|Huckleberry|Finn)", file_contents);
time_posix = true;
}
output_html_results(false, "%long_twain_search%");
output_final_html();
return 0;
}

95
performance/pcre.cpp Normal file
View File

@ -0,0 +1,95 @@
///////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. 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_
//
#ifdef TEST_PCRE2
#define PCRE2_STATIC
#define PCRE2_CODE_UNIT_WIDTH 8
#include "performance.hpp"
#include <pcre2.h>
#include <boost/version.hpp>
#include <boost/lexical_cast.hpp>
struct pcre_regex : public abstract_regex
{
private:
pcre2_code* pe;
pcre2_match_data* pdata;
public:
pcre_regex()
: pe(0)
{
pdata = pcre2_match_data_create(30, NULL);
}
~pcre_regex()
{
if(pe)
pcre2_code_free(pe);
pcre2_match_data_free(pdata);
}
virtual bool set_expression(const char* pat, bool isperl)
{
if(!isperl)
return false;
if(pe)
pcre2_code_free(pe);
int errorcode = 0;
PCRE2_SIZE erroroffset;
pe = pcre2_compile((PCRE2_SPTR)pat, std::strlen(pat), PCRE2_MULTILINE, &errorcode, &erroroffset, NULL);
return pe ? true : false;
}
virtual bool match_test(const char* text);
virtual unsigned find_all(const char* text);
virtual std::string name();
struct initializer
{
initializer()
{
pcre_regex::register_instance(boost::shared_ptr<abstract_regex>(new pcre_regex));
}
void do_nothing()const {}
};
static const initializer init;
};
const pcre_regex::initializer pcre_regex::init;
bool pcre_regex::match_test(const char * text)
{
int r = pcre2_match(pe, (PCRE2_SPTR)text, std::strlen(text), 0, PCRE2_ANCHORED, pdata, NULL);
return r >= 0;
}
unsigned pcre_regex::find_all(const char * text)
{
unsigned count = 0;
int flags = 0;
const char* end = text + std::strlen(text);
while(pcre2_match(pe, (PCRE2_SPTR)text, end - text, 0, flags, pdata, NULL) >= 0)
{
++count;
PCRE2_SIZE* v = pcre2_get_ovector_pointer(pdata);
text += v[1];
if(v[0] == v[1])
++text;
if(*text)
{
flags = *(text - 1) == '\n' ? 0 : PCRE2_NOTBOL;
}
}
return count;
}
std::string pcre_regex::name()
{
init.do_nothing();
return std::string("PCRE-") + boost::lexical_cast<std::string>(PCRE2_MAJOR) + "." + boost::lexical_cast<std::string>(PCRE2_MINOR);
}
#endif

256
performance/performance.cpp Normal file
View File

@ -0,0 +1,256 @@
///////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. 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_
//
#include "performance.hpp"
#include <list>
#include <boost/chrono.hpp>
#include <boost/detail/lightweight_main.hpp>
#include <boost/regex.hpp>
#include <boost/filesystem.hpp>
void load_file(std::string& text, const char* file)
{
std::deque<char> temp_copy;
std::ifstream is(file);
if(!is.good())
{
std::string msg("Unable to open file: \"");
msg.append(file);
msg.append("\"");
throw std::runtime_error(msg);
}
is.seekg(0, std::ios_base::end);
std::istream::pos_type pos = is.tellg();
is.seekg(0, std::ios_base::beg);
text.erase();
text.reserve(pos);
std::istreambuf_iterator<char> it(is);
std::copy(it, std::istreambuf_iterator<char>(), std::back_inserter(text));
}
typedef std::list<boost::shared_ptr<abstract_regex> > list_type;
list_type& engines()
{
static list_type l;
return l;
}
void abstract_regex::register_instance(boost::shared_ptr<abstract_regex> item)
{
engines().push_back(item);
}
template <class Clock>
struct stopwatch
{
typedef typename Clock::duration duration;
stopwatch()
{
m_start = Clock::now();
}
duration elapsed()
{
return Clock::now() - m_start;
}
void reset()
{
m_start = Clock::now();
}
private:
typename Clock::time_point m_start;
};
unsigned sum = 0;
unsigned last_value_returned = 0;
template <class Func>
double exec_timed_test(Func f)
{
double t = 0;
unsigned repeats = 1;
do {
stopwatch<boost::chrono::high_resolution_clock> w;
for(unsigned count = 0; count < repeats; ++count)
{
last_value_returned = f();
sum += last_value_returned;
}
t = boost::chrono::duration_cast<boost::chrono::duration<double>>(w.elapsed()).count();
if(t < 0.5)
repeats *= 2;
} while(t < 0.5);
return t / repeats;
}
std::string format_expression_as_quickbook(std::string s)
{
static const boost::regex e("[`/_*=$^@#&%\\\\]");
static const boost::regex open_b("\\[");
static const boost::regex close_b("\\]");
s = regex_replace(s, e, "\\\\$0");
s = regex_replace(s, open_b, "\\\\u005B");
s = regex_replace(s, close_b, "\\\\u005D");
if(s.size() > 200)
{
s.erase(200);
s += " ...";
}
return "[^" + s + "]";
}
void test_match(const char* expression, const char* text, bool isperl = false)
{
std::string table = "Testing simple " + (isperl ? std::string("Perl") : std::string("leftmost-longest")) + " matches (platform = " + platform_name() + ", compiler = " + compiler_name() + ")";
std::string row = format_expression_as_quickbook(expression);
row += "[br]";
row += format_expression_as_quickbook(text);
for(list_type::const_iterator i = engines().begin(); i != engines().end(); ++i)
{
std::string heading = (*i)->name();
if((*i)->set_expression(expression, isperl))
{
double time = exec_timed_test([&]() { return (*i)->match_test(text) ? 1 : 0; });
report_execution_time(time, table, row, heading);
}
}
}
void test_search(const char* expression, const char* text, bool isperl = false, const char* filename = 0)
{
std::string table = "Testing " + (isperl ? std::string("Perl") : std::string("leftmost-longest")) + " searches (platform = " + platform_name() + ", compiler = " + compiler_name() + ")";
std::string row = format_expression_as_quickbook(expression);
row += "[br]";
if(filename)
{
row += "In file: ";
row += filename;
}
else
{
row += format_expression_as_quickbook(text);
}
for(list_type::const_iterator i = engines().begin(); i != engines().end(); ++i)
{
std::string heading = (*i)->name();
if((*i)->set_expression(expression, isperl))
{
double time = exec_timed_test([&]() { return (*i)->find_all(text); });
report_execution_time(time, table, row, heading);
std::cout << "Search with library: " << heading << " found " << last_value_returned << " occurances.\n";
}
}
}
int cpp_main(int argc, char* argv[])
{
boost::filesystem::path here(__FILE__);
here = here.parent_path().parent_path().parent_path().parent_path();
boost::filesystem::path cpp_file = here / "boost";
cpp_file /= "crc.hpp";
// start with a simple test, this is basically a measure of the minimal overhead
// involved in calling a regex matcher:
test_match("abc", "abc");
// these are from the regex docs:
test_match("^([0-9]+)(\\-| |$)(.*)$", "100- this is a line of ftp response which contains a message string");
test_match("([[:digit:]]{4}[- ]){3}[[:digit:]]{3,4}", "1234-5678-1234-456");
// these are from http://www.regxlib.com/
test_match("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$", "john@johnmaddock.co.uk");
test_match("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$", "foo12@foo.edu");
test_match("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$", "bob.smith@foo.tv");
test_match("^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$", "EH10 2QQ");
test_match("^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$", "G1 1AA");
test_match("^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$", "SW1 1ZZ");
test_match("^[[:digit:]]{1,2}/[[:digit:]]{1,2}/[[:digit:]]{4}$", "4/1/2001");
test_match("^[[:digit:]]{1,2}/[[:digit:]]{1,2}/[[:digit:]]{4}$", "12/12/2001");
test_match("^[-+]?[[:digit:]]*\\.?[[:digit:]]*$", "123");
test_match("^[-+]?[[:digit:]]*\\.?[[:digit:]]*$", "+3.14159");
test_match("^[-+]?[[:digit:]]*\\.?[[:digit:]]*$", "-3.14159");
// start with a simple test, this is basically a measure of the minimal overhead
// involved in calling a regex matcher:
test_match("abc", "abc", true);
// these are from the regex docs:
test_match("^([0-9]+)(\\-| |$)(.*)$", "100- this is a line of ftp response which contains a message string", true);
test_match("([[:digit:]]{4}[- ]){3}[[:digit:]]{3,4}", "1234-5678-1234-456", true);
// these are from http://www.regxlib.com/
test_match("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$", "john@johnmaddock.co.uk", true);
test_match("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$", "foo12@foo.edu", true);
test_match("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$", "bob.smith@foo.tv", true);
test_match("^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$", "EH10 2QQ", true);
test_match("^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$", "G1 1AA", true);
test_match("^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$", "SW1 1ZZ", true);
test_match("^[[:digit:]]{1,2}/[[:digit:]]{1,2}/[[:digit:]]{4}$", "4/1/2001", true);
test_match("^[[:digit:]]{1,2}/[[:digit:]]{1,2}/[[:digit:]]{4}$", "12/12/2001", true);
test_match("^[-+]?[[:digit:]]*\\.?[[:digit:]]*$", "123", true);
test_match("^[-+]?[[:digit:]]*\\.?[[:digit:]]*$", "+3.14159", true);
test_match("^[-+]?[[:digit:]]*\\.?[[:digit:]]*$", "-3.14159", true);
std::string file_contents;
const char* highlight_expression = // preprocessor directives: index 1
"(^[ \\t]*#(?:(?>[^\\\\\\n]+)|\\\\(?>\\s*\\n|.))*)|";
// comment: index 2
"(//[^\\n]*|/\\*.*?\\*/)|"
// literals: index 3
"\\<([+-]?(?:(?:0x[[:xdigit:]]+)|(?:(?:[[:digit:]]*\\.)?[[:digit:]]+(?:[eE][+-]?[[:digit:]]+)?))u?(?:(?:int(?:8|16|32|64))|L)?)\\>|"
// string literals: index 4
"('(?:[^\\\\']|\\\\.)*'|\"(?:[^\\\\\"]|\\\\.)*\")|"
// keywords: index 5
"\\<(__asm|__cdecl|__declspec|__export|__far16|__fastcall|__fortran|__import"
"|__pascal|__rtti|__stdcall|_asm|_cdecl|__except|_export|_far16|_fastcall"
"|__finally|_fortran|_import|_pascal|_stdcall|__thread|__try|asm|auto|bool"
"|break|case|catch|cdecl|char|class|const|const_cast|continue|default|delete"
"|do|double|dynamic_cast|else|enum|explicit|extern|false|float|for|friend|goto"
"|if|inline|int|long|mutable|namespace|new|operator|pascal|private|protected"
"|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_cast"
"|struct|switch|template|this|throw|true|try|typedef|typeid|typename|union|unsigned"
"|using|virtual|void|volatile|wchar_t|while)\\>"
;
const char* class_expression = "(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
"(class|struct)[[:space:]]*(\\w+([ \t]*\\([^)]*\\))?"
"[[:space:]]*)*(\\w*)[[:space:]]*(<[^;:{]+>[[:space:]]*)?"
"(\\{|:[^;\\{()]*\\{)";
const char* call_expression = "\\w+\\s*(\\([^()]++(?:(?1)[^()]++)*+[^)]*\\))";
const char* include_expression = "^[ \t]*#[ \t]*include[ \t]+(\"[^\"]+\"|<[^>]+>)";
const char* boost_include_expression = "^[ \t]*#[ \t]*include[ \t]+(\"boost/[^\"]+\"|<boost/[^>]+>)";
const char* brace_expression = "\\{[^{}]++((?0)[^{}]++)*+[^}]*+\\}";
const char* function_with_body_expression = "(\\w+)\\s*(\\([^()]++(?:(?2)[^()]++)*+[^)]*\\))\\s*(\\{[^{}]++((?3)[^{}]++)*+[^}]*+\\})";
load_file(file_contents, "../../../libs/libraries.htm");
test_search("Beman|John|Dave", file_contents.c_str(), false, "../../../libs/libraries.htm");
test_search("Beman|John|Dave", file_contents.c_str(), true, "../../../libs/libraries.htm");
test_search("(?i)<p>.*?</p>", file_contents.c_str(), true, "../../../libs/libraries.htm");
test_search("<a[^>]+href=(\"[^\"]*\"|[^[:space:]]+)[^>]*>", file_contents.c_str(), false, "../../../libs/libraries.htm");
test_search("(?i)<a[^>]+href=(\"[^\"]*\"|[^[:space:]]+)[^>]*>", file_contents.c_str(), true, "../../../libs/libraries.htm");
test_search("(?i)<h[12345678][^>]*>.*?</h[12345678]>", file_contents.c_str(), true, "../../../libs/libraries.htm");
test_search("<img[^>]+src=(\"[^\"]*\"|[^[:space:]]+)[^>]*>", file_contents.c_str(), false, "../../../libs/libraries.htm");
test_search("(?i)<img[^>]+src=(\"[^\"]*\"|[^[:space:]]+)[^>]*>", file_contents.c_str(), true, "../../../libs/libraries.htm");
test_search("(?i)<font[^>]+face=(\"[^\"]*\"|[^[:space:]]+)[^>]*>.*?</font>", file_contents.c_str(), true, "../../../libs/libraries.htm");
load_file(file_contents, "../../../boost/multiprecision/number.hpp");
test_search(function_with_body_expression, file_contents.c_str(), true, "boost/multiprecision/number.hpp");
test_search(brace_expression, file_contents.c_str(), true, "boost/multiprecision/number.hpp");
test_search(call_expression, file_contents.c_str(), true, "boost/multiprecision/number.hpp");
test_search(highlight_expression, file_contents.c_str(), true, "boost/multiprecision/number.hpp");
test_search(class_expression, file_contents.c_str(), true, "boost/multiprecision/number.hpp");
test_search(include_expression, file_contents.c_str(), true, "boost/multiprecision/number.hpp");
test_search(boost_include_expression, file_contents.c_str(), true, "boost/multiprecision/number.hpp");
return 0;
}

View File

@ -0,0 +1,30 @@
///////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. 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_
//
#ifndef BOOST_REGEX_PERFRMANCE_HPP
#define BOOST_REGEX_PERFRMANCE_HPP
#include <string>
#include <boost/shared_ptr.hpp>
struct abstract_regex
{
virtual bool set_expression(const char*, bool isperl) = 0;
virtual bool match_test(const char* text) = 0;
virtual unsigned find_all(const char* text) = 0;
virtual std::string name() = 0;
static void register_instance(boost::shared_ptr<abstract_regex> item);
};
void report_execution_time(double t, std::string table, std::string row, std::string heading);
std::string boost_name();
std::string compiler_name();
std::string platform_name();
#endif

96
performance/posix.cpp Normal file
View File

@ -0,0 +1,96 @@
///////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. 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_
//
#ifdef TEST_POSIX
#include "performance.hpp"
#include <boost/lexical_cast.hpp>
#include <regex.h>
struct posix_regex : public abstract_regex
{
private:
regex_t pe, pe2;
bool init;
public:
posix_regex() : pe, init(false) {}
~posix_regex()
{
if(init)
{
regfree(&pe);
regfree(&pe2);
}
}
virtual bool set_expression(const char* pat, bool isperl)
{
if(isperl)
return false;
if(init)
{
regfree(&pe);
regfree(&pe2);
}
else
init = true;
int r = regcomp(&pe, pat, REG_EXTENDED);
std::string s(pat);
if(s.size() && (s[0] != '^'))
s.insert(0, 1, '^');
if(s.size() && (*s.rbegin() != '$'))
s.append("$");
r |= regcomp(&pe2, s.c_str(), REG_EXTENDED);
return r ? false : true;
}
virtual bool match_test(const char* text);
virtual unsigned find_all(const char* text);
virtual std::string name();
struct initializer
{
initializer()
{
posix_regex::register_instance(boost::shared_ptr<abstract_regex>(new posix_regex));
}
void do_nothing()const {}
};
static const initializer init;
};
const posix_regex::initializer posix_regex::init;
bool posix_regex::match_test(const char * text)
{
regmatch_t m[30];
int r = regexec(&pe2, text, 30, m, 0);
return r == 0;
}
unsigned posix_regex::find_all(const char * text)
{
unsigned count = 0;
regmatch_t m[30];
int flags = 0;
while(regexec(&pe, text, 30, m, flags) == 0)
{
++count;
text = m[0].rm_so;
if(*text)
++text;
flags = REG_NOTBOL;
}
return 0;
}
std::string posix_regex::name()
{
init.do_nothing();
return "POSIX";
}
#endif

71
performance/re2.cpp Normal file
View File

@ -0,0 +1,71 @@
///////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. 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_
//
#ifdef TEST_RE2
#include "performance.hpp"
#include <boost/scoped_ptr.hpp>
#include <re2.h>
using namespace re2;
struct re2_regex : public abstract_regex
{
private:
boost::scoped_ptr<RE2> pat;
public:
re2_regex() {}
~re2_regex(){}
virtual bool set_expression(const char* pp, bool isperl)
{
if(!isperl)
return false;
std::string s("(?m)");
s += pp;
pat.reset(new RE2(s));
return pat->ok();
}
virtual bool match_test(const char* text);
virtual unsigned find_all(const char* text);
virtual std::string name();
struct initializer
{
initializer()
{
re2_regex::register_instance(boost::shared_ptr<abstract_regex>(new re2_regex));
}
void do_nothing()const {}
};
static const initializer init;
};
const re2_regex::initializer re2_regex::init;
bool re2_regex::match_test(const char * text)
{
return RE2::FullMatch(text, *pat);
}
unsigned re2_regex::find_all(const char * text)
{
unsigned count = 0;
StringPiece input(text);
while(RE2::FindAndConsume(&input, *pat))
{
++count;
}
return count;
}
std::string re2_regex::name()
{
init.do_nothing();
return "RE2";
}
#endif

View File

@ -1,158 +0,0 @@
/*
*
* 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)
*
*/
#ifndef REGEX_COMPARISON_HPP
#define REGEX_COMPARISON_HPP
#include <string>
#include <list>
#include <boost/limits.hpp>
//
// globals:
//
extern bool time_boost;
extern bool time_localised_boost;
extern bool time_greta;
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;
extern bool test_long_twain;
extern bool test_code;
extern bool test_html;
extern std::string html_template_file;
extern std::string html_out_file;
extern std::string html_contents;
int handle_argument(const std::string& what);
int show_usage();
void load_file(std::string& text, const char* file);
void output_html_results(bool show_description, const std::string& tagname);
void output_final_html();
struct results
{
double boost_time;
double localised_boost_time;
double greta_time;
double safe_greta_time;
double posix_time;
double pcre_time;
double xpressive_time;
double std_time;
double factor;
std::string expression;
std::string description;
results(const std::string& ex, const std::string& desc)
: boost_time(-1),
localised_boost_time(-1),
greta_time(-1),
safe_greta_time(-1),
posix_time(-1),
pcre_time(-1),
xpressive_time(-1),
std_time(-1),
factor((std::numeric_limits<double>::max)()),
expression(ex),
description(desc)
{}
void finalise()
{
if((boost_time >= 0) && (boost_time < factor))
factor = boost_time;
if((localised_boost_time >= 0) && (localised_boost_time < factor))
factor = localised_boost_time;
if((greta_time >= 0) && (greta_time < factor))
factor = greta_time;
if((safe_greta_time >= 0) && (safe_greta_time < factor))
factor = safe_greta_time;
if((posix_time >= 0) && (posix_time < factor))
factor = posix_time;
if((pcre_time >= 0) && (pcre_time < factor))
factor = pcre_time;
if((xpressive_time >= 0) && (xpressive_time < factor))
factor = xpressive_time;
if((std_time >= 0) && (std_time < factor))
factor = std_time;
}
};
extern std::list<results> result_list;
namespace b {
// boost 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);
}
namespace bl {
// localised boost 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);
}
namespace pcr {
// pcre 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);
}
namespace g {
// greta 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);
}
namespace gs {
// safe greta 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);
}
namespace posix {
// safe greta 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);
}
namespace dxpr {
// 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);
}
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);
inline void test_match(const std::string& re, const std::string& text, bool icase = false)
{ test_match(re, text, text, icase); }
inline void test_find_all(const std::string& re, const std::string& text, bool icase = false)
{ test_find_all(re, text, "", icase); }
#define REPEAT_COUNT 10
#endif

73
performance/std.cpp Normal file
View File

@ -0,0 +1,73 @@
///////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. 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_
//
#include <boost/config.hpp>
#ifndef BOOST_NO_CXX11_HDR_REGEX
#include "performance.hpp"
#include <regex>
struct std_regex : public abstract_regex
{
private:
std::regex e;
std::cmatch what;
public:
virtual bool set_expression(const char* pe, bool isperl)
{
try
{
e.assign(pe, isperl ? std::regex::ECMAScript : std::regex::extended);
}
catch(const std::exception&)
{
return false;
}
return true;
}
virtual bool match_test(const char* text);
virtual unsigned find_all(const char* text);
virtual std::string name();
struct initializer
{
initializer()
{
std_regex::register_instance(boost::shared_ptr<abstract_regex>(new std_regex));
}
void do_nothing()const {}
};
static const initializer init;
};
const std_regex::initializer std_regex::init;
bool std_regex::match_test(const char * text)
{
return regex_match(text, what, e);
}
unsigned std_regex::find_all(const char * text)
{
std::regex_iterator<const char*> i(text, text + std::strlen(text), e), j;
unsigned count = 0;
while(i != j)
{
++i;
++count;
}
return count;
}
std::string std_regex::name()
{
init.do_nothing();
return "std::regex";
}
#endif

View File

@ -0,0 +1,413 @@
// Copyright John Maddock 2015.
// 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)
#ifdef _MSC_VER
# pragma warning (disable : 4224)
#endif
#include <boost/regex.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <vector>
#include <set>
#include <iostream>
#include <sstream>
#include <iomanip>
std::vector<std::vector<double> > data;
inline std::string sanitize_string(const std::string& s)
{
static const boost::regex e("[^a-zA-Z0-9]+");
std::string result = boost::regex_replace(s, e, "_");
while(result[0] == '_')
result.erase(0);
return result;
}
std::string format_precision(double val, int digits)
{
std::stringstream ss;
ss << std::setprecision(digits);
ss << std::fixed;
ss << val;
return ss.str();
}
static std::string content;
boost::filesystem::path path_to_content;
struct content_loader
{
content_loader()
{
boost::filesystem::path p(__FILE__);
p = p.parent_path();
p /= "doc";
p /= "performance_tables.qbk";
path_to_content = p;
if(boost::filesystem::exists(p))
{
boost::filesystem::ifstream is(p);
if(is.good())
{
do
{
char c = static_cast<char>(is.get());
if(c != EOF)
content.append(1, c);
} while(is.good());
}
}
}
~content_loader()
{
boost::filesystem::ofstream os(path_to_content);
os << content;
}
void instantiate()const
{
}
};
static const content_loader loader;
void load_table(std::vector<std::vector<std::string> >& table, std::string::const_iterator begin, std::string::const_iterator end)
{
static const boost::regex item_e(
"\\["
"([^\\[\\]]*(?0)?)*"
"\\]"
);
boost::regex_token_iterator<std::string::const_iterator> i(begin, end, item_e), j;
while(i != j)
{
// Add a row:
table.push_back(std::vector<std::string>());
boost::regex_token_iterator<std::string::const_iterator> k(i->first + 1, i->second - 1, item_e);
while(k != j)
{
// Add a cell:
table.back().push_back(std::string(k->first + 1, k->second - 1));
++k;
}
++i;
}
}
std::string save_table(std::vector<std::vector<std::string> >& table)
{
std::string result;
for(std::vector<std::vector<std::string> >::const_iterator i = table.begin(), j = table.end(); i != j; ++i)
{
result += "[";
for(std::vector<std::string>::const_iterator k = i->begin(), l = i->end(); k != l; ++k)
{
result += "[";
result += *k;
result += "]";
}
result += "]\n";
}
return result;
}
void add_to_all_sections(const std::string& id, std::string list_name = "performance_all_sections")
{
std::string::size_type pos = content.find("[template " + list_name + "[]"), end_pos;
if(pos == std::string::npos)
{
//
// Just append to the end:
//
content.append("\n[template ").append(list_name).append("[]\n[").append(id).append("]\n]\n");
}
else
{
//
// Read in the all list of sections, add our new one (in alphabetical order),
// and then rewrite the whole thing:
//
static const boost::regex item_e(
"\\["
"((?=[^\\]])[^\\[\\]]*+(?0)?+)*+"
"\\]|\\]"
);
boost::regex_token_iterator<std::string::const_iterator> i(content.begin() + pos + 12 + list_name.size(), content.end(), item_e), j;
std::set<std::string> sections;
while(i != j)
{
if(i->length() == 1)
{
end_pos = i->first - content.begin();
break;
}
sections.insert(std::string(i->first + 1, i->second - 1));
++i;
}
sections.insert(id);
std::string new_list = "\n";
for(std::set<std::string>::const_iterator sec = sections.begin(); sec != sections.end(); ++sec)
{
new_list += "[" + *sec + "]\n";
}
content.replace(pos + 12 + list_name.size(), end_pos - pos - 12 - list_name.size(), new_list);
}
}
std::string get_colour(boost::uintmax_t val, boost::uintmax_t best)
{
if(val <= best * 1.2)
return "green";
if(val > best * 4)
return "red";
return "blue";
}
boost::intmax_t get_value_from_cell(const std::string& cell)
{
static const boost::regex time_e("(\\d+)ns");
boost::smatch what;
if(regex_search(cell, what, time_e))
{
return boost::lexical_cast<boost::uintmax_t>(what.str(1));
}
return -1;
}
void add_cell(boost::intmax_t val, const std::string& table_name, const std::string& row_name, const std::string& column_heading)
{
//
// Load the table, add our data, and re-write:
//
std::string table_id = "table_" + sanitize_string(table_name);
boost::regex table_e("\\[table:" + table_id
+ "\\s(?:[^\\[]|\\\\.)++"
"((\\["
"((?:[^\\[\\]]|\\\\.)*+(?2)?+)*+"
"\\]\\s*+)*+\\s*+)"
"\\]"
);
boost::smatch table_location;
if(regex_search(content, table_location, table_e))
{
std::vector<std::vector<std::string> > table_data;
load_table(table_data, table_location[1].first, table_location[1].second);
//
// Figure out which column we're on:
//
unsigned column_id = 1001u;
for(unsigned i = 0; i < table_data[0].size(); ++i)
{
if(table_data[0][i] == column_heading)
{
column_id = i;
break;
}
}
if(column_id > 1000)
{
//
// Need a new column, must be adding a new compiler to the table!
//
table_data[0].push_back(column_heading);
for(unsigned i = 1; i < table_data.size(); ++i)
table_data[i].push_back(std::string());
column_id = table_data[0].size() - 1;
}
//
// Figure out the row:
//
unsigned row_id = 1001;
for(unsigned i = 1; i < table_data.size(); ++i)
{
if(table_data[i][0] == row_name)
{
row_id = i;
break;
}
}
if(row_id > 1000)
{
//
// Need a new row, add it now:
//
table_data.push_back(std::vector<std::string>());
table_data.back().push_back(row_name);
for(unsigned i = 1; i < table_data[0].size(); ++i)
table_data.back().push_back(std::string());
row_id = table_data.size() - 1;
}
//
// Find the best result in this row:
//
boost::uintmax_t best = (std::numeric_limits<boost::uintmax_t>::max)();
std::vector<boost::intmax_t> values;
for(unsigned i = 1; i < table_data[row_id].size(); ++i)
{
if(i == column_id)
{
if(val < best)
best = val;
values.push_back(val);
}
else
{
std::cout << "Existing cell value was " << table_data[row_id][i] << std::endl;
boost::uintmax_t cell_val = get_value_from_cell(table_data[row_id][i]);
std::cout << "Extracted value: " << cell_val << std::endl;
if(cell_val < best)
best = cell_val;
values.push_back(cell_val);
}
}
//
// Update the row:
//
for(unsigned i = 1; i < table_data[row_id].size(); ++i)
{
std::string& s = table_data[row_id][i];
s = "[role ";
if(values[i - 1] < 0)
{
s += "grey -]";
}
else
{
s += get_colour(values[i - 1], best);
s += " ";
s += format_precision(static_cast<double>(values[i - 1]) / best, 2);
s += "[br](";
s += boost::lexical_cast<std::string>(values[i - 1]) + "ns)]";
}
}
//
// Convert back to a string and insert into content:
std::sort(table_data.begin() + 1, table_data.end(), [](std::vector<std::string> const& a, std::vector<std::string> const& b) { return a[0] < b[0]; } );
std::string c = save_table(table_data);
content.replace(table_location.position(1), table_location.length(1), c);
}
else
{
//
// Create a new table and try again:
//
std::string new_table = "\n[template " + table_id;
new_table += "[]\n[table:" + table_id;
new_table += " ";
new_table += table_name;
new_table += "\n[[Expression[br]Text][";
new_table += column_heading;
new_table += "]]\n";
new_table += "[[";
new_table += row_name;
new_table += "][[role blue 1.00[br](";
new_table += boost::lexical_cast<std::string>(val);
new_table += "ns)]]]\n]\n]\n";
std::string::size_type pos = content.find("[/tables:]");
if(pos != std::string::npos)
content.insert(pos + 10, new_table);
else
content += "\n\n[/tables:]\n" + new_table;
//
// Add a section for this table as well:
//
std::string section_id = "section_" + sanitize_string(table_name);
if(content.find(section_id + "[]") == std::string::npos)
{
std::string new_section = "\n[template " + section_id + "[]\n[section:" + section_id + " " + table_name + "]\n[" + table_id + "]\n[endsect]\n]\n";
pos = content.find("[/sections:]");
if(pos != std::string::npos)
content.insert(pos + 12, new_section);
else
content += "\n\n[/sections:]\n" + new_section;
add_to_all_sections(section_id);
}
//
// Add to list of all tables (not in sections):
//
add_to_all_sections(table_id, "performance_all_tables");
}
}
void report_execution_time(double t, std::string table, std::string row, std::string heading)
{
try {
add_cell(static_cast<boost::uintmax_t>(t / 1e-9), table, row, heading);
}
catch(const std::exception& e)
{
std::cout << "Error in adding cell: " << e.what() << std::endl;
throw;
}
}
std::string boost_name()
{
return "boost " + boost::lexical_cast<std::string>(BOOST_VERSION / 100000) + "." + boost::lexical_cast<std::string>((BOOST_VERSION / 100) % 1000);
}
std::string compiler_name()
{
#ifdef COMPILER_NAME
return COMPILER_NAME;
#else
return BOOST_COMPILER;
#endif
}
std::string platform_name()
{
#ifdef _WIN32
return "Windows x64";
#else
return BOOST_PLATFORM;
#endif
}
std::string get_compiler_options_name()
{
#if defined(BOOST_MSVC) || defined(__ICL)
std::string result;
#ifdef BOOST_MSVC
result = "cl ";
#else
result = "icl ";
#endif
#ifdef _M_AMD64
#ifdef __AVX__
result += "/arch:AVX /Ox";
#else
result += "/Ox";
#endif
result += " (x64 build)";
#else
#ifdef _DEBUG
result += "/Od";
#elif defined(__AVX2__)
result += "/arch:AVX2 /Ox";
#elif defined(__AVX__)
result += "/arch:AVX /Ox";
#elif _M_IX86_FP == 2
result += "/arch:sse2 /Ox";
#else
result += "/arch:ia32 /Ox";
#endif
result += " (x86 build)";
#endif
std::cout << "Compiler options are found as: " << result << std::endl;
return result;
#else
return "Unknown";
#endif
}

View File

@ -1,119 +0,0 @@
/*
*
* 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"
#include <iostream>
#include <boost/timer.hpp>
#include <boost/regex.hpp>
namespace b{
double time_match(const std::string& re, const std::string& text, bool icase)
{
try{
boost::regex e(re, (icase ? boost::regex::perl | boost::regex::icase : boost::regex::perl));
boost::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)
{
boost::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)
{
boost::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 boost::smatch&)
{ return true; }
struct noop
{
void operator()( boost::smatch const & ) const
{
}
};
double time_find_all(const std::string& re, const std::string& text, bool icase)
{
try{
boost::regex e(re, (icase ? boost::regex::perl | boost::regex::icase : boost::regex::perl));
boost::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)
{
boost::sregex_iterator begin( text.begin(), text.end(), e ), end;
std::for_each( begin, end, noop() );
//boost::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)
{
boost::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;
}
}
}

View File

@ -1,144 +0,0 @@
/*
*
* Copyright (c) 2004
* 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"
#ifdef BOOST_HAS_XPRESSIVE
#include <cassert>
#include <iostream>
#include <boost/timer.hpp>
#include <boost/xpressive/xpressive.hpp>
namespace dxpr
{
double time_match(const std::string& re, const std::string& text, bool icase)
{
try{
boost::xpressive::regex_constants::syntax_option_type flags = boost::xpressive::regex_constants::optimize;
if(icase)
flags = flags | boost::xpressive::regex_constants::icase;
boost::xpressive::sregex e(boost::xpressive::sregex::compile(re, flags));
boost::xpressive::smatch what;
boost::timer tim;
int iter = 1;
int counter, repeats;
double result = 0;
double run;
assert(boost::xpressive::regex_match( text, what, e ));
do
{
tim.restart();
for(counter = 0; counter < iter; ++counter)
{
boost::xpressive::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)
{
boost::xpressive::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;
}
}
struct noop
{
void operator()( boost::xpressive::smatch const & ) const
{
}
};
double time_find_all(const std::string& re, const std::string& text, bool icase)
{
try{
boost::xpressive::regex_constants::syntax_option_type flags = boost::xpressive::regex_constants::optimize;
if(icase)
flags = flags | boost::xpressive::regex_constants::icase;
boost::xpressive::sregex e(boost::xpressive::sregex::compile(re, flags));
boost::xpressive::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)
{
boost::xpressive::sregex_iterator begin( text.begin(), text.end(), e ), end;
std::for_each( begin, end, noop() );
}
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)
{
boost::xpressive::sregex_iterator begin( text.begin(), text.end(), e ), end;
std::for_each( begin, end, noop() );
}
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;
}
}
}
#else
namespace dxpr{
double time_match(const std::string& re, const std::string& text, bool icase)
{
return -1;
}
double time_find_all(const std::string& re, const std::string& text, bool icase)
{
return -1;
}
}
#endif

View File

@ -1,122 +0,0 @@
/*
*
* 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"
#if defined(BOOST_HAS_GRETA)
#include <cassert>
#include <boost/timer.hpp>
#include "regexpr2.h"
namespace g{
double time_match(const std::string& re, const std::string& text, bool icase)
{
regex::rpattern e(re, (icase ? regex::MULTILINE | regex::NORMALIZE | regex::NOCASE : regex::MULTILINE | regex::NORMALIZE));
regex::match_results what;
boost::timer tim;
int iter = 1;
int counter, repeats;
double result = 0;
double run;
assert(e.match(text, what));
do
{
tim.restart();
for(counter = 0; counter < iter; ++counter)
{
e.match(text, what);
}
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)
{
e.match(text, what);
}
run = tim.elapsed();
result = (std::min)(run, result);
}
return result / iter;
}
double time_find_all(const std::string& re, const std::string& text, bool icase)
{
regex::rpattern e(re, (icase ? regex::MULTILINE | regex::NORMALIZE | regex::NOCASE : regex::MULTILINE | regex::NORMALIZE));
regex::match_results what;
boost::timer tim;
int iter = 1;
int counter, repeats;
double result = 0;
double run;
do
{
tim.restart();
for(counter = 0; counter < iter; ++counter)
{
e.match(text.begin(), text.end(), what);
while(what.backref(0).matched)
{
e.match(what.backref(0).end(), text.end(), what);
}
}
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)
{
e.match(text.begin(), text.end(), what);
while(what.backref(0).matched)
{
e.match(what.backref(0).end(), text.end(), what);
}
}
run = tim.elapsed();
result = (std::min)(run, result);
}
return result / iter;
}
}
#else
namespace g {
double time_match(const std::string& re, const std::string& text, bool icase)
{
return -1;
}
double time_find_all(const std::string& re, const std::string& text, bool icase)
{
return -1;
}
}
#endif

View File

@ -1,107 +0,0 @@
/*
*
* 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"
#include <boost/timer.hpp>
#include <boost/regex.hpp>
namespace bl{
double time_match(const std::string& re, const std::string& text, bool icase)
{
boost::basic_regex<char, boost::cpp_regex_traits<char> > e(re, (icase ? boost::regex::perl | boost::regex::icase : boost::regex::perl));
boost::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)
{
boost::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)
{
boost::regex_match(text, what, e);
}
run = tim.elapsed();
result = (std::min)(run, result);
}
return result / iter;
}
bool dummy_grep_proc(const boost::smatch&)
{ return true; }
struct noop
{
void operator()( boost::smatch const & ) const
{
}
};
double time_find_all(const std::string& re, const std::string& text, bool icase)
{
boost::basic_regex<char, boost::cpp_regex_traits<char> > e(re, (icase ? boost::regex::perl | boost::regex::icase : boost::regex::perl));
boost::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)
{
boost::regex_iterator<
std::string::const_iterator,
char,
boost::cpp_regex_traits<char> > begin( text.begin(), text.end(), e ), end;
std::for_each( begin, end, noop() );
//boost::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)
{
boost::regex_grep(&dummy_grep_proc, text, e);
}
run = tim.elapsed();
result = (std::min)(run, result);
}
return result / iter;
}
}

View File

@ -1,176 +0,0 @@
/*
*
* 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 <cassert>
#include <cfloat>
#include "regex_comparison.hpp"
#ifdef BOOST_HAS_PCRE
#include "pcre.h"
#include <boost/timer.hpp>
namespace pcr{
double time_match(const std::string& re, const std::string& text, bool icase)
{
pcre *ppcre;
const char *error;
int erroffset;
int what[50];
boost::timer tim;
int iter = 1;
int counter, repeats;
double result = 0;
double run;
if(0 == (ppcre = pcre_compile(re.c_str(), (icase ? PCRE_CASELESS | PCRE_ANCHORED | PCRE_DOTALL | PCRE_MULTILINE : PCRE_ANCHORED | PCRE_DOTALL | PCRE_MULTILINE),
&error, &erroffset, NULL)))
{
free(ppcre);
return -1;
}
pcre_extra *pe;
pe = pcre_study(ppcre, 0, &error);
if(error)
{
free(ppcre);
free(pe);
return -1;
}
do
{
tim.restart();
for(counter = 0; counter < iter; ++counter)
{
erroffset = pcre_exec(ppcre, pe, text.c_str(), text.size(), 0, 0, what, sizeof(what)/sizeof(int));
}
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)
{
erroffset = pcre_exec(ppcre, pe, text.c_str(), text.size(), 0, 0, what, sizeof(what)/sizeof(int));
}
run = tim.elapsed();
result = (std::min)(run, result);
}
free(ppcre);
free(pe);
return result / iter;
}
double time_find_all(const std::string& re, const std::string& text, bool icase)
{
pcre *ppcre;
const char *error;
int erroffset;
int what[50];
boost::timer tim;
int iter = 1;
int counter, repeats;
double result = 0;
double run;
int exec_result;
int matches;
if(0 == (ppcre = pcre_compile(re.c_str(), (icase ? PCRE_CASELESS | PCRE_DOTALL | PCRE_MULTILINE : PCRE_DOTALL | PCRE_MULTILINE), &error, &erroffset, NULL)))
{
free(ppcre);
return -1;
}
pcre_extra *pe;
pe = pcre_study(ppcre, 0, &error);
if(error)
{
free(ppcre);
free(pe);
return -1;
}
do
{
int startoff;
tim.restart();
for(counter = 0; counter < iter; ++counter)
{
matches = 0;
startoff = 0;
exec_result = pcre_exec(ppcre, pe, text.c_str(), text.size(), startoff, 0, what, sizeof(what)/sizeof(int));
while(exec_result >= 0)
{
++matches;
startoff = what[1];
exec_result = pcre_exec(ppcre, pe, text.c_str(), text.size(), startoff, 0, what, sizeof(what)/sizeof(int));
}
}
result = tim.elapsed();
iter *= 2;
}while(result < 0.5);
iter /= 2;
if(result >10)
return result / iter;
result = DBL_MAX;
// repeat test and report least value for consistency:
for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
{
int startoff;
matches = 0;
tim.restart();
for(counter = 0; counter < iter; ++counter)
{
matches = 0;
startoff = 0;
exec_result = pcre_exec(ppcre, pe, text.c_str(), text.size(), startoff, 0, what, sizeof(what)/sizeof(int));
while(exec_result >= 0)
{
++matches;
startoff = what[1];
exec_result = pcre_exec(ppcre, pe, text.c_str(), text.size(), startoff, 0, what, sizeof(what)/sizeof(int));
}
}
run = tim.elapsed();
result = (std::min)(run, result);
}
return result / iter;
}
}
#else
namespace pcr{
double time_match(const std::string& re, const std::string& text, bool icase)
{
return -1;
}
double time_find_all(const std::string& re, const std::string& text, bool icase)
{
return -1;
}
}
#endif

View File

@ -1,139 +0,0 @@
/*
*
* 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 <cassert>
#include <cfloat>
#include "regex_comparison.hpp"
#ifdef BOOST_HAS_POSIX
#include <boost/timer.hpp>
#include "regex.h"
namespace posix{
double time_match(const std::string& re, const std::string& text, bool icase)
{
regex_t e;
regmatch_t what[20];
boost::timer tim;
int iter = 1;
int counter, repeats;
double result = 0;
double run;
if(0 != ::regcomp(&e, re.c_str(), (icase ? REG_ICASE | REG_EXTENDED : REG_EXTENDED)))
return -1;
do
{
tim.restart();
for(counter = 0; counter < iter; ++counter)
{
regexec(&e, text.c_str(), e.re_nsub, what, 0);
}
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)
{
regexec(&e, text.c_str(), e.re_nsub, what, 0);
}
run = tim.elapsed();
result = (std::min)(run, result);
}
regfree(&e);
return result / iter;
}
double time_find_all(const std::string& re, const std::string& text, bool icase)
{
regex_t e;
regmatch_t what[20];
memset(what, 0, sizeof(what));
boost::timer tim;
int iter = 1;
int counter, repeats;
double result = 0;
double run;
int exec_result;
int matches;
if(0 != regcomp(&e, re.c_str(), (icase ? REG_ICASE | REG_EXTENDED : REG_EXTENDED)))
return -1;
do
{
tim.restart();
for(counter = 0; counter < iter; ++counter)
{
what[0].rm_so = 0;
what[0].rm_eo = text.size();
matches = 0;
exec_result = regexec(&e, text.c_str(), 20, what, REG_STARTEND);
while(exec_result == 0)
{
++matches;
what[0].rm_so = what[0].rm_eo;
what[0].rm_eo = text.size();
exec_result = regexec(&e, text.c_str(), 20, what, REG_STARTEND);
}
}
result = tim.elapsed();
iter *= 2;
}while(result < 0.5);
iter /= 2;
if(result >10)
return result / iter;
result = DBL_MAX;
// repeat test and report least value for consistency:
for(repeats = 0; repeats < REPEAT_COUNT; ++repeats)
{
tim.restart();
for(counter = 0; counter < iter; ++counter)
{
what[0].rm_so = 0;
what[0].rm_eo = text.size();
matches = 0;
exec_result = regexec(&e, text.c_str(), 20, what, REG_STARTEND);
while(exec_result == 0)
{
++matches;
what[0].rm_so = what[0].rm_eo;
what[0].rm_eo = text.size();
exec_result = regexec(&e, text.c_str(), 20, what, REG_STARTEND);
}
}
run = tim.elapsed();
result = (std::min)(run, result);
}
return result / iter;
}
}
#else
namespace posix{
double time_match(const std::string& re, const std::string& text, bool icase)
{
return -1;
}
double time_find_all(const std::string& re, const std::string& text, bool icase)
{
return -1;
}
}
#endif

View File

@ -1,124 +0,0 @@
/*
*
* 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"
#if defined(BOOST_HAS_GRETA)
#include <cassert>
#include <boost/timer.hpp>
#include "regexpr2.h"
namespace gs{
double time_match(const std::string& re, const std::string& text, bool icase)
{
regex::rpattern e(re, (icase ? regex::MULTILINE | regex::NORMALIZE | regex::NOCASE : regex::MULTILINE | regex::NORMALIZE), regex::MODE_SAFE);
regex::match_results what;
boost::timer tim;
int iter = 1;
int counter, repeats;
double result = 0;
double run;
assert(e.match(text, what));
do
{
tim.restart();
for(counter = 0; counter < iter; ++counter)
{
e.match(text, what);
}
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)
{
e.match(text, what);
}
run = tim.elapsed();
result = (std::min)(run, result);
}
return result / iter;
}
double time_find_all(const std::string& re, const std::string& text, bool icase)
{
regex::rpattern e(re, (icase ? regex::MULTILINE | regex::NORMALIZE | regex::NOCASE : regex::MULTILINE | regex::NORMALIZE), regex::MODE_SAFE);
regex::match_results what;
boost::timer tim;
int iter = 1;
int counter, repeats;
double result = 0;
double run;
do
{
bool r;
tim.restart();
for(counter = 0; counter < iter; ++counter)
{
e.match(text.begin(), text.end(), what);
while(what.backref(0).matched)
{
e.match(what.backref(0).end(), text.end(), what);
}
}
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)
{
e.match(text.begin(), text.end(), what);
while(what.backref(0).matched)
{
e.match(what.backref(0).end(), text.end(), what);
}
}
run = tim.elapsed();
result = (std::min)(run, result);
}
return result / iter;
}
}
#else
namespace gs{
double time_match(const std::string& re, const std::string& text, bool icase)
{
return -1;
}
double time_find_all(const std::string& re, const std::string& text, bool icase)
{
return -1;
}
}
#endif

View File

@ -1,123 +0,0 @@
/*
*
* 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_CXX11_HDR_REGEX
#include <iostream>
#include <boost/timer.hpp>
#include <regex>
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

74
performance/xpressive.cpp Normal file
View File

@ -0,0 +1,74 @@
///////////////////////////////////////////////////////////////
// Copyright 2015 John Maddock. 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_
//
#include <boost/config.hpp>
#include "performance.hpp"
#include <boost/xpressive/xpressive.hpp>
using namespace boost::xpressive;
struct xpressive_regex : public abstract_regex
{
private:
cregex e;
cmatch what;
public:
virtual bool set_expression(const char* pe, bool isperl)
{
if(!isperl)
return false;
try
{
e = cregex::compile(pe, regex_constants::ECMAScript);
}
catch(const std::exception&)
{
return false;
}
return true;
}
virtual bool match_test(const char* text);
virtual unsigned find_all(const char* text);
virtual std::string name();
struct initializer
{
initializer()
{
xpressive_regex::register_instance(boost::shared_ptr<abstract_regex>(new xpressive_regex));
}
void do_nothing()const {}
};
static const initializer init;
};
const xpressive_regex::initializer xpressive_regex::init;
bool xpressive_regex::match_test(const char * text)
{
return regex_match(text, what, e);
}
unsigned xpressive_regex::find_all(const char * text)
{
cregex_token_iterator i(text, text + std::strlen(text), e), j;
unsigned count = 0;
while(i != j)
{
++i;
++count;
}
return count;
}
std::string xpressive_regex::name()
{
init.do_nothing();
return "boost::xpressive::cregex";
}