📄 regex_timer.cpp
字号:
/* * * Copyright (c) 1998-2002 * Dr John Maddock * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Dr John Maddock makes no representations * about the suitability of this software for any purpose. * It is provided "as is" without express or implied warranty. * */#include <string>#include <algorithm>#include <deque>#include <iterator>#ifdef BOOST_RE_OLD_IOSTREAM#include <iostream.h>#include <fstream.h>#else#include <iostream>#include <fstream>using std::cout;using std::cin;using std::cerr;using std::istream;using std::ostream;using std::endl;using std::ifstream;using std::streambuf;using std::getline;#endif#include <boost/config.hpp>#include <boost/regex.hpp>#include <boost/timer.hpp> #include <boost/smart_ptr.hpp>#if defined(_MSC_VER) && (_MSC_VER <= 1300)// maybe no Koenig lookup, use using declaration instead:using namespace boost;#endif#ifndef BOOST_NO_WREGEXostream& operator << (ostream& os, const std::wstring& s){ std::wstring::const_iterator i, j; i = s.begin(); j = s.end(); while(i != j) { os.put(*i); ++i; } return os;}#endiftemplate <class S>class string_out_iterator #ifndef BOOST_NO_STD_ITERATOR : public std::iterator<std::output_iterator_tag, void, void, void, void>#endif // ndef BOOST_NO_STD_ITERATOR{#ifdef BOOST_NO_STD_ITERATOR typedef std::output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference;#endif // BOOST_NO_STD_ITERATOR S* out;public: string_out_iterator(S& s) : out(&s) {} string_out_iterator& operator++() { return *this; } string_out_iterator& operator++(int) { return *this; } string_out_iterator& operator*() { return *this; } string_out_iterator& operator=(typename S::value_type v) { out->append(1, v); return *this; }};#if defined(BOOST_MSVC) || (defined(__BORLANDC__) && (__BORLANDC__ == 0x550)) || defined(__SGI_STL_PORT)//// problem with std::getline under MSVC6sp3// and C++ Builder 5.5, is this really that hard?istream& getline(istream& is, std::string& s){ s.erase(); char c = is.get(); while(c != '\n') { s.append(1, c); c = is.get(); } return is;}#endifint main(int argc, char**argv){ ifstream ifs; streambuf* pbuf = 0; if(argc == 2) { ifs.open(argv[1]); if(ifs.bad()) { cout << "Bad filename: " << argv[1] << endl; return -1; } pbuf = cin.rdbuf(ifs.rdbuf()); } boost::regex ex; boost::match_results<std::string::const_iterator> sm;#ifndef BOOST_NO_WREGEX std::wstring ws1, ws2; boost::wregex wex; boost::match_results<std::wstring::const_iterator> wsm;#endif boost::match_results<std::deque<char>::iterator> dm; std::string s1, s2, ts; std::deque<char> ds; boost::regex_t r; boost::scoped_array<boost::regmatch_t> matches; std::size_t nsubs; boost::timer t; double tim; bool result; int iters = 100; double wait_time = std::min(t.elapsed_min() * 1000, 1.0); while(true) { cout << "Enter expression (or \"quit\" to exit): "; getline(cin, s1); if(argc == 2) cout << endl << s1 << endl; if(s1 == "quit") break;#ifndef BOOST_NO_WREGEX ws1.erase(); std::copy(s1.begin(), s1.end(), string_out_iterator<std::wstring>(ws1));#endif try{ ex.assign(s1);#ifndef BOOST_NO_WREGEX wex.assign(ws1);#endif } catch(std::exception& e) { cout << "Error in expression: \"" << e.what() << "\"" << endl; continue; } int code = regcomp(&r, s1.c_str(), boost::REG_PERL); if(code != 0) { char buf[256]; regerror(code, &r, buf, 256); cout << "regcomp error: \"" << buf << "\"" << endl; continue; } nsubs = r.re_nsub + 1; matches.reset(new boost::regmatch_t[nsubs]); while(true) { cout << "Enter string to search (or \"quit\" to exit): "; getline(cin, s2); if(argc == 2) cout << endl << s2 << endl; if(s2 == "quit") break;#ifndef BOOST_NO_WREGEX ws2.erase(); std::copy(s2.begin(), s2.end(), string_out_iterator<std::wstring>(ws2));#endif ds.erase(ds.begin(), ds.end()); std::copy(s2.begin(), s2.end(), std::back_inserter(ds)); int i; iters = 10; tim = 1.1;#if defined(_WIN32) && defined(BOOST_REGEX_USE_WIN32_LOCALE) MSG msg; PeekMessage(&msg, 0, 0, 0, 0); Sleep(0);#endif // cache load: regex_search(s2, sm, ex); // measure time interval for reg_expression<char> do{ iters *= (tim > 0.001) ? (1.1/tim) : 100; t.restart(); for(i =0; i < iters; ++i) { result = regex_search(s2, sm, ex); } tim = t.elapsed(); }while(tim < wait_time); cout << "regex time: " << (tim * 1000000 / iters) << "us" << endl; if(result) { for(i = 0; i < sm.size(); ++i) { ts = sm[i]; cout << "\tmatch " << i << ": \""; cout << ts; cout << "\" (matched=" << sm[i].matched << ")" << endl; } cout << "\tmatch $`: \""; cout << std::string(sm[-1]); cout << "\" (matched=" << sm[-1].matched << ")" << endl; cout << "\tmatch $': \""; cout << std::string(sm[-2]); cout << "\" (matched=" << sm[-2].matched << ")" << endl << endl; }#ifndef BOOST_NO_WREGEX // measure time interval for boost::wregex iters = 10; tim = 1.1; // cache load: regex_search(ws2, wsm, wex); do{ iters *= (tim > 0.001) ? (1.1/tim) : 100; t.restart(); for(i = 0; i < iters; ++i) { result = regex_search(ws2, wsm, wex); } tim = t.elapsed(); }while(tim < wait_time); cout << "wregex time: " << (tim * 1000000 / iters) << "us" << endl; if(result) { std::wstring tw; for(i = 0; i < wsm.size(); ++i) { tw.erase(); std::copy(wsm[i].first, wsm[i].second, string_out_iterator<std::wstring>(tw)); cout << "\tmatch " << i << ": \"" << tw; cout << "\" (matched=" << sm[i].matched << ")" << endl; } cout << "\tmatch $`: \""; tw.erase(); std::copy(wsm[-1].first, wsm[-1].second, string_out_iterator<std::wstring>(tw)); cout << tw; cout << "\" (matched=" << sm[-1].matched << ")" << endl; cout << "\tmatch $': \""; tw.erase(); std::copy(wsm[-2].first, wsm[-2].second, string_out_iterator<std::wstring>(tw)); cout << tw; cout << "\" (matched=" << sm[-2].matched << ")" << endl << endl; }#endif // measure time interval for reg_expression<char> using a deque iters = 10; tim = 1.1; // cache load: regex_search(ds.begin(), ds.end(), dm, ex); do{ iters *= (tim > 0.001) ? (1.1/tim) : 100; t.restart(); for(i = 0; i < iters; ++i) { result = regex_search(ds.begin(), ds.end(), dm, ex); } tim = t.elapsed(); }while(tim < wait_time); cout << "regex time (search over std::deque<char>): " << (tim * 1000000 / iters) << "us" << endl; if(result) { for(i = 0; i < dm.size(); ++i) { ts.erase(); std::copy(dm[i].first, dm[i].second, string_out_iterator<std::string>(ts)); cout << "\tmatch " << i << ": \"" << ts; cout << "\" (matched=" << sm[i].matched << ")" << endl; } cout << "\tmatch $`: \""; ts.erase(); std::copy(dm[-1].first, dm[-1].second, string_out_iterator<std::string>(ts)); cout << ts; cout << "\" (matched=" << sm[-1].matched << ")" << endl; cout << "\tmatch $': \""; ts.erase(); std::copy(dm[-2].first, dm[-2].second, string_out_iterator<std::string>(ts)); cout << ts; cout << "\" (matched=" << sm[-2].matched << ")" << endl << endl; } // measure time interval for POSIX matcher: iters = 10; tim = 1.1; // cache load: regexec(&r, s2.c_str(), nsubs, matches.get(), 0); do{ iters *= (tim > 0.001) ? (1.1/tim) : 100; t.restart(); for(i = 0; i < iters; ++i) { result = regexec(&r, s2.c_str(), nsubs, matches.get(), 0); } tim = t.elapsed(); }while(tim < wait_time); cout << "POSIX regexec time: " << (tim * 1000000 / iters) << "us" << endl; if(result == 0) { for(i = 0; i < nsubs; ++i) { if(matches[i].rm_so >= 0) { ts.assign(s2.begin() + matches[i].rm_so, s2.begin() + matches[i].rm_eo); cout << "\tmatch " << i << ": \"" << ts << "\" (matched=" << (matches[i].rm_so != -1) << ")"<< endl; } else cout << "\tmatch " << i << ": \"\" (matched=" << (matches[i].rm_so != -1) << ")" << endl; // no match } cout << "\tmatch $`: \""; ts.erase(); ts.assign(s2.begin(), s2.begin() + matches[0].rm_so); cout << ts; cout << "\" (matched=" << (matches[0].rm_so != 0) << ")" << endl; cout << "\tmatch $': \""; ts.erase(); ts.assign(s2.begin() + matches[0].rm_eo, s2.end()); cout << ts; cout << "\" (matched=" << (matches[0].rm_eo != s2.size()) << ")" << endl << endl; } } regfree(&r); } if(pbuf) cin.rdbuf(pbuf); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -