Почему мой Perl regex использует так много памяти? - PullRequest
5 голосов
/ 03 октября 2008

Я использую регулярное выражение для большого скаляра. Хотя этот матч ничего не захватывает, мой процесс увеличивается на 30 миллионов после этого матча:

# A
if (${$c} =~ m/\G<<\s*/cgs)
{
    #B
    ...
}

$c является ссылкой на довольно большой скаляр (около 21M), но я убедился, что pos(${$c}) находится в правильном месте, и выражение соответствует первому символу, при этом pos(${$c}) обновляется до правильное место после матча. Но, как я уже говорил, процесс между #A и #B вырос примерно на 30 млн., Хотя я не собираю ничего с этим совпадением. Куда уходит моя память?

Редактировать: Да, виновато было использование $&. Мы используем Perl 5.8.8, а мой скрипт использовал Getopt :: Declare , который использует встроенный Text :: Balanced . Версия 1.95 этого модуля использовала $&. Версия 2.0.0, поставляемая с Perl 5.10, удалила ссылку на $& и устраняет проблему.

1 Ответ

20 голосов
/ 03 октября 2008

Просто быстрая проверка работоспособности, вы упоминаете $ &, $ `или $ '(иногда называемые $ MATCH, $ PREMATCH и $ POSTMATCH) где-нибудь в вашем коде? Если это так, Perl скопирует всю вашу строку для каждого совпадения с регулярным выражением, на тот случай, если вы захотите проверить эти переменные.

«В вашем коде» в данном случае означает косвенно, включая использование модулей, которые ссылаются на эти переменные, или запись use English вместо use English qw( -no_match_vars ).

Если вы не уверены, вы можете использовать модуль Devel :: SawAmpersand , чтобы определить, были ли они использованы, и Devel :: FindAmpersand , чтобы выяснить где они используются.

Могут быть и другие причины увеличения памяти (какую версию Perl вы используете?), Но переменные соответствия определенно унесут вашу память, если они будут использованы, и, следовательно, являются вероятным виновником.

Cheerio

Пол

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...