The OpenNET Project / Index page

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




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
awk быстрее perl ?, !*! greenwar, 11-Ноя-09, 03:50  [смотреть все]
..или это я ещё совсем зелёный?

есть задачка:
из файла:
Name: network1
Dropped packets: 15618
Dropped packets for IPv6: 27
Dropped packets: 74
Dropped packets for IPv6: 0
Failed RADIUS Authentication procedures: 0
Failed RADIUS Accounting procedures: 0
Name: network2
Dropped packets: 1117
Dropped packets for IPv6: 0
Dropped packets: 0
Dropped packets for IPv6: 0
Failed RADIUS Authentication procedures: 0
Failed RADIUS Accounting procedures: 0

сделать:
network1:15618:27:74:0:0:0
network2:1117:0:0:0:0:0

файл, соот-но, увеличить до мегов 300 (я на таком тестил) банальным размножением блоков по 7 строк..

решение на awk:
awk -F': *' ' { r = r ? r ":" $2 : $2 } /^Failed RADIUS Accounting procedures/{ print r; r = 0 } ' infile > outfile

голову грел больше 2х часов, но максимум, чего добился, это вот такого решения на perl:
#!/usr/bin/perl -w

open(FH,"infile");
open(NEW,">outfile");
while(<FH>){
    if(/: (network\d+?)$/){print NEW "\n$1";next}
    /: (\d+)$/;print NEW ":$1"
}

awk отрабатывает за 29 сек, перл за 40..
как оптимизировать код на perl до такого уровня?

  • awk быстрее perl ?, !*! ACCA, 07:27 , 11-Ноя-09 (1)
    >..или это я ещё совсем зелёный?

    Кокетничаешь. Можно выжать разве что ещё пяток процентов по мелочи типа


    #!/usr/bin/perl -w

    while(<>){
        if(/: (network\d+)/){print "\n$1";next}
        /: (\d+)/;print ":$1"
    }

    - нет $ в конце regexp и \d+ вместо \d+?.

    А вот времена на 400M файле совсем даже обратные:


    $ time ./counter.pl datafile.txt > /dev/null

    real    0m26.809s
    user    0m26.510s
    sys    0m0.290s

    $ time awk -F': *' ' { r = r ? r ":" $2 : $2 } /^Failed RADIUS Accounting procedures/{ print r; r = 0 }' datafile.txt > /dev/null

    real    0m54.194s
    user    0m53.950s
    sys    0m0.240s

    $ uname -a
    Linux hostname 2.6.31-14-generic #48-Ubuntu SMP Fri Oct 16 14:05:01 UTC 2009 x86_64 GNU/Linux
    $ awk --version
    GNU Awk 3.1.6
    $ perl --version
    This is perl, v5.10.0 built for x86_64-linux-gnu-thread-multi


    Если время обработки настолько критично, я бы не постеснялся написать на C.

    • awk быстрее perl ?, !*! greenwar, 10:19 , 11-Ноя-09 (2)
      >Кокетничаешь.

      та не.. месяц назад я о перле знал ровно 0

      >- нет $ в конце regexp и \d+ вместо \d+?.

      а вот зря их там нет.. на моей машине это увеличивает время на 3 секунды
      из книжки запомнил, что унарные + * сами по себе жадные, ищут максимальную длину, а с ? ищут минимальную. при $ должен искать с конца строки, а не с начала
      вообщем, регулярке так зона поиска сужается похоже раза в 2

      >А вот времена на 400M файле совсем даже обратные:

      хмхм.. значит, перл у меня не оптимизирован на производительность и ядро тоже
      +целерон на буке стоит, а не SMP

      >Если время обработки настолько критично, я бы не постеснялся написать на C.

      та не, просто удивился, что перл, как и авк, написан на си, заточен под обработку текста, как никто, а при этом сливает

      • awk быстрее perl ?, !*! svn, 11:33 , 11-Ноя-09 (3)
        >та не, просто удивился, что перл, как и авк, написан на си,
        >заточен под обработку текста, как никто, а при этом сливает

        У них разные регулярные выражения. В awk более быстрые основанные на конечных автоматах, в perl более функциональные.

        PS: Парсер на С (flex) обойдёт их в десятки раз ))

        • awk быстрее perl ?, !*! Pahanivo, 14:03 , 11-Ноя-09 (4)
          >>та не, просто удивился, что перл, как и авк, написан на си,
          >>заточен под обработку текста, как никто, а при этом сливает
          >
          >У них разные регулярные выражения. В awk более быстрые основанные на конечных
          >автоматах, в perl более функциональные.
          >
          >PS: Парсер на С (flex) обойдёт их в десятки раз ))

          а в шаблонном файле не быстрее подстроку сравнить чем regex заюзать?

    • awk быстрее perl ?, !*! Vladin, 22:52 , 14-Ноя-09 (5)
      +1
      перл быстрее
      у меня время на 300М файле по этим скриптам
      awk: 1 мин 40 сек
      perl: 29 сек

      вариант без регулярок: 22 сек

      open(FH,"infile");
      open(NEW,">outfile");
      while(<FH>){
        chop;
        $_  = substr( $_, index($_,':')+2 );
        if( ord($_) == 110 ) {
          print NEW "\n$_";
          next;
        }
        print NEW ":$_";
      }

      • awk быстрее perl ?, !*! greenwar, 15:26 , 15-Ноя-09 (6)
        >[оверквотинг удален]
        >open(NEW,">outfile");
        >while(<FH>){
        >  chop;
        >  $_  = substr( $_, index($_,':')+2 );
        >  if( ord($_) == 110 ) {
        >    print NEW "\n$_";
        >    next;
        >  }
        >  print NEW ":$_";
        >}

        чё-то ляпов многовато..

        >  chop;

        плохая привычка чопать конец строки, можно чопнуть чего-нить нужное
        лучше чомпать (chomp)

        >  $_  = substr( $_, index($_,':')+2 );

        а где гарантия, что будет именно 2 символа в конце строки? даже в примере есть далеко не 2

        так и регуляркой можно было строгать треть строк мимо.. было бы быстрее :)
        к тому же, вы несложную регулярку на 3 функции заменили.. шило на мыло имхо

        >  if( ord($_) == 110 ) {

        регуляркой это: /: \D+$/

        • awk быстрее perl ?, !*! Vladin, 16:48 , 15-Ноя-09 (7)
          >>  chop;
          >
          >плохая привычка чопать конец строки, можно чопнуть чего-нить нужное
          >лучше чомпать (chomp)

          согласен, изначально был chomp, в ходе эксперимента заменил на chop, выиграл 1 сек

          >>  $_  = substr( $_, index($_,':')+2 );
          >
          >а где гарантия, что будет именно 2 символа в конце строки? даже
          >в примере есть далеко не 2

          тут не то, ищем где стоит дветочие и отрезаем его и пробел за ним
          т.е. убираем название параметра, оставляя только значение

          >так и регуляркой можно было строгать треть строк мимо.. было бы быстрее
          >:)
          >к тому же, вы несложную регулярку на 3 функции заменили.. шило на
          >мыло имхо

          7 сек из 29 = 24%, далеко не шило
          в регулярке больше работает комп, в моем случае - программист

          >>  if( ord($_) == 110 ) {
          >
          >регуляркой это: /: \D+$/

          нет, это проверка что первый символ в строке равен 'n'
          взято из идеологии си, там строка является массивом и работает конструкция string[0] == 'n'

          • awk быстрее perl ?, !*! greenwar, 12:09 , 16-Ноя-09 (8)
            >согласен, изначально был chomp, в ходе эксперимента заменил на chop, выиграл 1
            >сек

            странно.. по идее работают по одному принципу

            >>>  $_  = substr( $_, index($_,':')+2 );
            >>
            >>а где гарантия, что будет именно 2 символа в конце строки? даже
            >>в примере есть далеко не 2
            >
            >тут не то, ищем где стоит дветочие и отрезаем его и пробел
            >за ним
            >т.е. убираем название параметра, оставляя только значение

            а index и регекспы разными механизмами находят двоеточие в строке?

            >>так и регуляркой можно было строгать треть строк мимо.. было бы быстрее
            >>:)
            >>к тому же, вы несложную регулярку на 3 функции заменили.. шило на
            >>мыло имхо
            >
            >7 сек из 29 = 24%, далеко не шило
            >в регулярке больше работает комп, в моем случае - программист

            хорошо, если так, но пока не ясно, откуда такая большая разница между index и регекспом. ищут одно и тоже, а механизмы настолько разные?
            полезная тема для познания дао оптимизации

            >>>  if( ord($_) == 110 ) {
            >>
            >>регуляркой это: /: \D+$/
            >
            >нет, это проверка что первый символ в строке равен 'n'
            >взято из идеологии си, там строка является массивом и работает конструкция string[0]
            >== 'n'

            нутк /: \D+$/ означает любое НЕ число после двоеточия. если он встретит там туже букву 'n', сработает if

            • awk быстрее perl ?, !*! greenwar, 11:25 , 29-Май-10 (9)
              тэкс, тут появилась ещё одна непонятка.. теперь PHP быстрее Perl на регулярках ^^
              поможете разобраться в причинах?

              <?php
              $fp = fopen('text.txt', 'rt');
              while (!feof($fp)) {
                $str = fgets($fp);
                for($i=0; $i<100; $i++) {
                  $pattern_str = rand(100, 1000);
                  preg_match_all('/'.$pattern_str.'/', $str, $out);
                }
              }
              ?>

              в 3 раза быстрее, чем:

              #!/usr/bin/perl -w

              while(<>){ # обрабатываем построчно указанный файл. формат запуска скрипта: time ./script textfile

                  for(0..99){ # цикл на 10к раз. в каждой строке 10000 раз ищем рандомное число от 100 до 1000
                      $searchline=(int rand(901)+100); # строка для поиска: рандомное целое число от 100 до 1000
                      $_=~/$searchline/g; # ищем регекспом с продолжением поиска по строке после 1го совпадения
                  }
              }

              в качестве файла берётся обычный 20-меговый архив или бинарник или текстовик




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

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