Я работаю над проектом встроенного cpp, и мне нужно работать над регулярным выражением в одном из компонентов 'X'. Следовательно, я использовал простой regcomp / regexec в своем приложении для конкретного компонента 'X'.
Компонент 'X' принимает в качестве входных данных непрерывный текстовый буфер и для фильтрации нескольких журналов я использовал 10 простых выражений с API-интерфейсом regcomp / regexec. Чтобы проверить производительность, я оставил устройство нетронутым / потревоженным более 12 часов, и когда я проверял команду «top», «VSZ%» этого конкретного компонента составляет ~ 95%, а CPU% - около ~ 16%
Вот мои вопросы:
- Почему простой regcomp / regexec занимает ~ 16% процессорного времени? Может быть, в качестве входных данных используется непрерывный текстовый буфер и для фильтрации RegEx каждый раз он собирается ~ 16%? Это ожидается / это слишком высоко, учитывая простой API RegEx?
- Что может быть причиной того, что компонент 'X' принимает ~ 95% VSZ%? Опять же, это ожидается? Если так, то почему?
Псевдокод ниже:
#include <regex.h>
class ComponentX
{
public:
ComponentX();
virtual ~ComponentX() throw ();
private:
regex_t RegEx1;
regex_t RegEx2;
regex_t RegEx3;
regex_t RegEx4;
regex_t RegEx5;
regex_t RegEx6;
regex_t RegEx7;
regex_t RegEx8;
regex_t RegEx9;
regex_t RegEx10;
}
// Constructor
ComponentX::ComponentX():
{
const char* Pattern1 = "^12";
const char* Pattern2 = "REQUEST$";
const char* Pattern3 = "^Key$";
const char* Pattern4 = "client";
const char* Pattern5 = "Fre*";
const char* Pattern6 = "Buf{2,5}";
const char* Pattern7 = "C(b|l)";
const char* Pattern8 = "^.$";
const char* Pattern9 = "E(b*|R*)R";
const char* Pattern10 = "m.t";
regcomp(&RegEx1, Pattern1, 0);
regcomp(&RegEx2, Pattern2, 0);
regcomp(&RegEx3, Pattern3, 0);
regcomp(&RegEx4, Pattern4, 0);
regcomp(&RegEx5, Pattern5, 0);
regcomp(&RegEx6, Pattern6, 0);
regcomp(&RegEx7, Pattern7, 0);
regcomp(&RegEx8, Pattern8, 0);
regcomp(&RegEx9, Pattern9, 0);
regcomp(&RegEx10, Pattern10, 0);
}
// This method will be invoked continuously
void ComponentX::LogReceived(int logserverSeq, const char* module, long sec, long usec, int pid, int level, int /* seq */, const char* msg)
{
char buf[BUFSIZE];
struct tm* tm = ::localtime(&sec);
const char* levelStr = "<unknown>";
bool bRegEx1 = false;
bool bRegEx2 = false;
bool bRegEx3 = false;
bool bRegEx4 = false;
bool bRegEx5 = false;
bool bRegEx6 = false;
bool bRegEx7 = false;
bool bRegEx8 = false;
bool bRegEx9 = false;
bool bRegEx10 = false;
// Prepare the string
const size_t count = ::snprintf(buf, BUFSIZE, "%d %s %d %02d:%02d:%02d.%03ld %s(%d) %s: %s: %s: %s\n",logserverSeq,Months[tm->tm_mon],tm->tm_mday,tm->tm_hour,tm->tm_min, tm->tm_sec, usec / 1000, module, pid, levelStr,Product.c_str(),SerialNo.c_str(),msg);
// Check for all Regular expressions
if (0 == regexec(&RegEx1, buf, 0, NULL, 0)) {
bRegEx1 = true;
}
if (0 == regexec(&RegEx2, buf, 0, NULL, 0)) {
bRegEx2 = true;
}
if (0 == regexec(&RegEx3, buf, 0, NULL, 0)) {
bRegEx3 = true;
}
if (0 == regexec(&RegEx4, buf, 0, NULL, 0)) {
bRegEx4 = true;
}
if (0 == regexec(&RegEx5, buf, 0, NULL, 0)) {
bRegEx5 = true;
}
if (0 == regexec(&RegEx6, buf, 0, NULL, 0)) {
bRegEx6 = true;
}
if (0 == regexec(&RegEx7, buf, 0, NULL, 0)) {
bRegEx7 = true;
}
if (0 == regexec(&RegEx8, buf, 0, NULL, 0)) {
bRegEx8 = true;
}
if (0 == regexec(&RegEx9, buf, 0, NULL, 0)) {
bRegEx9 = true;
}
if (0 == regexec(&RegEx10, buf, 0, NULL, 0)) {
bRegEx10 = true;
}
// If any one RegEx is passed, notify the callback
if (bRegEx1 == true || bRegEx2 == true || bRegEx3 == true || bRegEx4 == true ||bRegEx5 == true || bRegEx6 == true || bRegEx7 == true || bRegEx8 == true || bRegEx9 == true || bRegEx10 == true ) {
if (count > 0) {
for (auto i = Loggers.begin(); i != Loggers.end(); ++i) {
(*i)->SendLog(buf, count);
}
}
}
}