假设我有以下功能:
bool IsNumber(std::string const& str)
{
return std::regex_match(str, std::regex{"\\d+"});
}
我正在构建std::regex
每个电话。这样做会记录性能开销吗?如果改成static
会不会更好,如下所示?
bool IsNumber(std::string const& str)
{
static std::regex const number_regex{"\\d+"};
return std::regex_match(str, number_regex);
}
或者这不重要吗?
答案 0 :(得分:1)
编译器可能无法识别每次调用时std :: regex的构造是否相等(例如,构造函数可以访问静态/全局变量)。因此,安全的方法是在任何情况下构建它。另一方面,现在的编译器非常聪明,也许他会深深地解析构造函数,以便意识到它必须随着时间的推移而保持不变,从而优化出来。无论如何:简介它。例如制作一个循环并测量几千次调用的时间(std :: chrono)(至少按秒的顺序)。 -
我制作了一个非常简单的测试程序来描述它:
#include <stdio.h>
#include <regex>
#include <chrono>
bool IsNumberA( std::string const& str )
{
return std::regex_match( str, std::regex { "\\d+" } );
}
static std::regex number_regex( "\\d+" );
bool IsNumberB( std::string const& str )
{
return std::regex_match( str, number_regex );
}
void main()
{
size_t count = 100000;
std::vector<std::string> aRandomStrings;
for( size_t i = 0; i < count; i++ )
aRandomStrings.push_back((rand() % 2 == 0) ? "nonumberatall" : "3141592");
auto time = std::chrono::system_clock::now();
size_t numberCountA = 0;
for( size_t i = 0; i < count; i++ )
if( IsNumberA( aRandomStrings[i] ) )
numberCountA++;
auto takenTimeA = std::chrono::duration_cast<std::chrono::milliseconds>
(std::chrono::system_clock::now() - time);
time = std::chrono::system_clock::now(); // reset
size_t numberCountB = 0;
for( size_t i = 0; i < count; i++ )
if( IsNumberB( aRandomStrings[i] ) )
numberCountB++;
auto takenTimeB = std::chrono::duration_cast<std::chrono::milliseconds>
(std::chrono::system_clock::now() - time);
printf( "took %d ms for A, %d ms for B\n", takenTimeA.count(), takenTimeB.count() );
}
<强>结果
我还没有进行优化编译它,只是为了看看编译器(msvc)是否足够智能。
A 6283ms,B 41ms
优化:268毫秒,B 85毫秒
使用预定义变量(B)时,我们可以清楚地看到性能的大幅提升。案例B中较慢的释放对我来说并不是很清楚,但时间尺度可能太低了。此外,随机生成器中可能还有很多未知的东西。