Любые предложения по улучшению (оптимизации) существующей подстановки строк в коде Perl? - PullRequest
4 голосов
/ 15 апреля 2011

Perl 5.8

Улучшения для довольно простых подстановок строк в существующем скрипте Perl.
Цель кода ясна, и код работает.

Для заданногоstring, замените каждое вхождение символа TAB, LF или CR одним пробелом и замените каждое вхождение двойной кавычки двумя двойными кавычками.Вот фрагмент из существующего кода:


# replace all tab, newline and return characters with single space
$val01  =~s/[\t\n\r]/ /g;
$val02  =~s/[\t\n\r]/ /g;
$val03  =~s/[\t\n\r]/ /g;

# escape all double quote characters by replacing with two double quotes
$val01  =~s/"/""/g;
$val02  =~s/"/""/g;
$val03  =~s/"/""/g;

Вопрос: Есть ли лучший способ выполнить эти манипуляции со строками?

By "лучший способ ", я имею в виду выполнять их более эффективно, избегая использования регулярных выражений (возможно, используя tr/// для замены символов табуляции, новой строки и lf) или, возможно, используя (qr//), чтобы избежать перекомпиляции.

ПРИМЕЧАНИЕ. Я рассмотрел возможность перемещения операций манипуляции со строками в подпрограмму, чтобы уменьшить количество повторений регулярных выражений.

ПРИМЕЧАНИЕ. Этот код работает, он на самом деле не нарушен.Я просто хочу знать, существует ли более подходящее соглашение о кодировании.

ПРИМЕЧАНИЕ. Эти операции выполняются в цикле с большим числом (> 10000) итераций.

ПРИМЕЧАНИЕ. Этот скриптв настоящее время выполняется под Perl v5.8.8.(Сценарий имеет require 5.6.0, но его можно изменить на require 5.8.8. (Установка более поздней версии Perl в настоящее время недоступна на производственном сервере.)


    > perl -v
    This is perl, v5.8.8 built for sun4-solaris-thread-multi
    (with 33 registered patches, see perl -V for more detail)

Ответы [ 4 ]

3 голосов
/ 15 апреля 2011

Ваше существующее решение выглядит хорошо для меня.

Что касается избежания перекомпиляции, вам не нужно беспокоиться об этом.Регулярные выражения Perl скомпилированы только один раз, как есть, если только они не содержат интерполированных выражений, чего нет у вас.

Ради полноты я должен отметить, что даже если присутствуют интерполированные выражения, вы можете сказать Perlскомпилировать регулярное выражение только один раз, указав флаг /o.

$var =~ s/foo/bar/;    # compiles once
$var =~ s/$foo/bar/;   # compiles each time
$var =~ s/$foo/bar/o;  # compiles once, using the value $foo has
                       # the first time the expression is evaluated
2 голосов
/ 15 ноября 2011

Я думаю, что tr/// будет (немного) быстрее, чем s/// в вашем первом регулярном выражении. Насколько быстрее, конечно, будет зависеть от факторов, которые я не знаю о вашей программе и вашей среде. Профилирование и бенчмаркинг ответят на этот вопрос.

Но если вас интересует какое-либо улучшение вашего кода, могу ли я предложить исправление ремонтопригодности? Вы выполняете одну и ту же замену (или набор замен) для трех переменных. Это означает, что когда вы меняете эту замену, вам нужно изменить ее три раза - и делать одно и то же три раза всегда опасно:)

Вы можете рассмотреть возможность рефакторинга кода, чтобы он выглядел примерно так:

foreach ($val01, $val02, $val03) {
    s/[\t\n\r]/ /g;
    s/"/""/g;
}

Кроме того, было бы неплохо иметь эти значения в массиве, а не три с одинаковыми именами переменных.

foreach (@vals) {
    s/[\t\n\r]/ /g;
    s/"/""/g;
}
2 голосов
/ 15 апреля 2011

Возможно, вы преждевременно оптимизируете.Вы пытались использовать профилировщик, такой как Devel :: NYTProf , чтобы увидеть, где ваша программа проводит большую часть своего времени?

2 голосов
/ 15 апреля 2011

TMTOWTDI

Вы можете использовать в качестве альтернативы функции tr или index или substr или split . Но вы должны сделать измерения, чтобы определить лучший метод для вашей конкретной системы.

...