Вычисления API простого регулярного выражения, занимающие много виртуальной памяти - PullRequest
0 голосов
/ 23 апреля 2019

Я работаю над проектом встроенного cpp, и мне нужно работать над регулярным выражением в одном из компонентов 'X'. Следовательно, я использовал простой regcomp / regexec в своем приложении для конкретного компонента 'X'.

Компонент 'X' принимает в качестве входных данных непрерывный текстовый буфер и для фильтрации нескольких журналов я использовал 10 простых выражений с API-интерфейсом regcomp / regexec. Чтобы проверить производительность, я оставил устройство нетронутым / потревоженным более 12 часов, и когда я проверял команду «top», «VSZ%» этого конкретного компонента составляет ~ 95%, а CPU% - около ~ 16%

Вот мои вопросы:

  1. Почему простой regcomp / regexec занимает ~ 16% процессорного времени? Может быть, в качестве входных данных используется непрерывный текстовый буфер и для фильтрации RegEx каждый раз он собирается ~ 16%? Это ожидается / это слишком высоко, учитывая простой API RegEx?
  2. Что может быть причиной того, что компонент '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);
      }
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...