The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Ускорить скрипт на Perl ???"
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы OpenNET: Виртуальная конференция (Public)
Изначальное сообщение [Проследить за развитием треда]

"Ускорить скрипт на Perl ???"
Сообщение от Андрей emailИскать по авторуВ закладки on 13-Июл-02, 23:40  (MSK)
Есть задача, уже решенная:
есть скрипт на Перле, который выполняет некоторые функции.
Дак вот, он считывает из конфига около 30-40 строк со строками кода,
потом в цикле исполняет их через eval($string)
Все бы ничего, но времени жрет много и памяти.
Переходить на другой алгоритм не хочеться - этот практически универсальный.
Как бы мне этот алгоритм оставить (т.е. чтобы в конфиге были строки кода), но ускорить выполнение ?
может есть какие-то модули ?
Или есть другие идеи ?
Для информации:
Система Slackware Linux+Perl5.6.1
скрипт пропущен через perlcc (Хотя и голый скрипт так же грузит машину)
память 64М - из них на скрипт уходит около 26-30%
машина селерон-333 - из них на скрипт около 70-80%
Есть идеи ?
  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "RE: Ускорить скрипт на Perl ???"
Сообщение от uldus Искать по авторуВ закладки on 14-Июл-02, 13:46  (MSK)
Оформи конфиг в виде Perl модуля или просто файла с perl кодом, подключай его через  require() в начале программы.
В любом случае понять текущую логику работы твоего скрипта и что можно оптимизировать не увидев код невозможно. Приведи кусок кода - получишь рекомендации по его оптимизации.
  Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "RE: Ускорить скрипт на Perl ???"
Сообщение от Андрей emailИскать по авторуВ закладки on 15-Июл-02, 08:31  (MSK)
>Оформи конфиг в виде Perl модуля или просто файла с perl кодом,
>подключай его через  require() в начале программы.
>В любом случае понять текущую логику работы твоего скрипта и что можно
>оптимизировать не увидев код невозможно. Приведи кусок кода - получишь рекомендации
>по его оптимизации.

Ну логика такова:
скрипту через конвейер на вход поступают данные от tcpdump.
в цикле эта строка обрабатывается при помощи как-раз кода из конфига:
open HLOG,"<$DATA";
while(<HLOG>)
{
    $logs=$_;
    if ($logs ne "") {
        ($SRCMAC,$DSTMAC,$LEN,$SADR,$flag,$DADR,$PROTO)=split('\ ',$logs);
         for ($i=0;$i<$calcnum;$i++) { # здесь как-раз идет цикл по всем строкам из конфига
            if (eval(@calc[$i])) { # OK.. value is TRUE
                $v=@calccode[$i];
                @calcvalue{$v}+=$LEN;
            }
        }
    }
}
ну вкратце вообщем-то и все.
а конфиг типа такого:
$DADR=~/^192.168.0.4$/
$DADR=~/^192.168.0.5$/ and not $SRCMAC=~/8:0:3e:2:5:12/
...
не хотелось бы отказываться от eval().
есть конечно вариант отказа от eval и изменении формата конфига, но не хотелось бы.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "RE: Ускорить скрипт на Perl ???"
Сообщение от uldus Искать по авторуВ закладки on 15-Июл-02, 11:08  (MSK)
>а конфиг типа такого:
>$DADR=~/^192.168.0.4$/

"eq" в данном случае будет на порядок быстрее, чем regex.

>$DADR=~/^192.168.0.5$/ and not $SRCMAC=~/8:0:3e:2:5:12/

А если правила задать в виде прцедуры, т.е.:
sub check_line{
       my ($ip_addr, $mac_addr) = @_;
   if ($ip_addr eq '192.168.0.4'){
      return 1;
   } elsif (($ip_addr eq '192.168.0.5') && !($mac_addr eq 'full_mac_addr')){
      return 1;
   } else {
      return 0;
   }
}

Если правила типовые, то лучше представить их в виде двух массивов:
@ip_allow=('192.168.0.4', '192.168.0.5');
%arp_fixation=('192.168.0.5' => '8:0:3e:2:5:12');

Логика работы:
sub check_line{
       my ($ip_addr, $mac_addr) = @_;
       my ($cur_ip, $cur_mac);

foreach $cur_ip (@ip_allow){
   if ($cur_ip eq $ip_addr){
      $cur_mac = $arp_fixation{$cur_ip};
      if ($cur_mac eq '' || $cur_mac eq $mac_addr){
          return 1;
      } else {
          return 0;
      }
   }
    return 0;
}

В обоих случаях, использование процедуры вместо цикла, подключение конфига через require().

  Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "RE: Ускорить скрипт на Perl ???"
Сообщение от Андрей emailИскать по авторуВ закладки on 15-Июл-02, 11:51  (MSK)
Процедуры ?
ну тогда вот придеться ужимать универсальность...
заменил я regex на простые операторы..
И как результат: время использования камня теперь уже около 47%
Неплохо, но иногда скачет и до 80%
все дело в том, что хочу без правки кода, добавлять новые правила в конфиг.
а если процедура - то уже такое не получится, либо - придется голову поломать на форматом конфига и реализацией алгоритма,
вообщем, морока.
хотя если другого решения не будет, придется...
а можа машину поменять ? есть у мея еще гиговая машина..хотя не.. так не интересно будет.
Смысл задачи-то как раз и такой: код определяет переменные,
а в конфиге я ими оперирую.
А может есть какие-то аналоги оператора eval() ??
  Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "RE: Ускорить скрипт на Perl ???"
Сообщение от uldus Искать по авторуВ закладки on 15-Июл-02, 12:30  (MSK)
>ну тогда вот придеться ужимать универсальность...

При использовании первого варианта универсальность нисколько не страдает, но я бы советовал использовать второй предложенный вариант. Все не предусмотришь, нужно четко определить какие требования предъявляются к твоему скрипту и сделать оптимальное выполнение этих функций. Чем грамотнее составлено тех. задание и предусмотреды все возможные варианты, тем меньше придется тратить времени при расширении функциональности системы в будущем.

>И как результат: время использования камня теперь уже около 47%
>Неплохо, но иногда скачет и до 80%

Это не выход, менять нужно алгоритм работы в корне, тогда призводительность вырастет не на 50%, а на 5000%. При этом универсальность пострадает на 5%.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "RE: Ускорить скрипт на Perl ???"
Сообщение от Андрей emailИскать по авторуВ закладки on 15-Июл-02, 13:40  (MSK)
>>ну тогда вот придеться ужимать универсальность...
>
>При использовании первого варианта универсальность нисколько не страдает, но я бы советовал
>использовать второй предложенный вариант. Все не предусмотришь, нужно четко определить какие
>требования предъявляются к твоему скрипту и сделать оптимальное выполнение этих функций.
>Чем грамотнее составлено тех. задание и предусмотреды все возможные варианты, тем
>меньше придется тратить времени при расширении функциональности системы в будущем.
>
>>И как результат: время использования камня теперь уже около 47%
>>Неплохо, но иногда скачет и до 80%
>
>Это не выход, менять нужно алгоритм работы в корне, тогда призводительность вырастет
>не на 50%, а на 5000%. При этом универсальность пострадает на
>5%.

Мне тоже так казалось, что нужно менять алгоритм, но не хотелось верить..:))
Вроде так славно получилось, а тут загруз. Хотя в данном случае ( анализ выхода от tcpdump ) на загруз нельзя не обращать внимание..
Кстати, вопрос: как поведет себя скрипт, если он не будет успевать обрабатывать входящие данные ?
Точнее, тут будет ситуация, когда скрипт не будет успевать считывать данные, которые ему поступают, и видимо как следствие - переполнение памяти под те дела, которые должны отвечать за конвейерную обработку ( т.е. система).
Но это практически на пальцах и может неверно.
Может кто поточнее объяснить может результат, когда данные поступают быстрее, чем считываются ?


  Рекомендовать в FAQ | Cообщить модератору | Наверх

7. "RE: Ускорить скрипт на Perl ???"
Сообщение от uldus Искать по авторуВ закладки on 15-Июл-02, 14:30  (MSK)
>Кстати, вопрос: как поведет себя скрипт, если он не будет успевать обрабатывать входящие данные ?

Срабатывает блокировка при выводе, если поток отрыт не в режиме "Non-blocking I/O", т.е. при выполнении очередного write(), выполнение программы остановится пока данные не будут переданы через этот write() (сам вызов write не будет завершен, соответственно программа будет остановлена).
При "Non-blocking I/O" вместо блокировки вывалится ошибка. Если пайп между процессом приемником и передатчиком разорвется (напрмер, умрет процесс приемник), процесс передатчик получит SIGPIPE.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

8. "RE: Ускорить скрипт на Perl ???"
Сообщение от Андрей emailИскать по авторуВ закладки on 15-Июл-02, 16:49  (MSK)
>Срабатывает блокировка при выводе, если поток отрыт не в режиме "Non-blocking I/O",
>т.е. при выполнении очередного write(), выполнение программы остановится пока данные не
>будут переданы через этот write() (сам вызов write не будет завершен,
>соответственно программа будет остановлена).

ну тогда такой вопрос - а как узнать, успевает или нет скрипт обрабатывать входной поток ?
я тут малость потестировал, вставил задержку в скрипт.с виду как будто все путем.а на самом деле думаю нет.
А вот как определить ?
данные посылает в поток tcpdump, и задержка секунд на 20 все-таки должна вызвать реакцию неуспевания при загрузе около 64Кбит.


  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру