The OpenNET Project / Index page

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

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

"Как уменьшить время выполнения программ на perl?"
Сообщение от RUSLAN Искать по авторуВ закладки on 14-Фев-03, 13:11  (MSK)
99 кб. текста прога обрабатывала около 8 сек., как можно сократить это время, хотя-бы в половину? Спасибо за внимание. :-)
  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

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

1. "RE: Как уменьшить время выполнения программ на perl?"
Сообщение от dawnshade emailИскать по авторуВ закладки on 14-Фев-03, 13:47  (MSK)
>99 кб. текста прога обрабатывала около 8 сек., как можно сократить это
>время, хотя-бы в половину? Спасибо за внимание. :-)

1) Переписать на C
2) Оптимизировать алгоритм. Чо делает-то? Текст кинь

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

2. "RE: Как уменьшить время выполнения программ на perl?"
Сообщение от RUSLAN Искать по авторуВ закладки on 14-Фев-03, 14:45  (MSK)
>>99 кб. текста прога обрабатывала около 8 сек., как можно сократить это
>>время, хотя-бы в половину? Спасибо за внимание. :-)
>
>1) Переписать на C
>2) Оптимизировать алгоритм. Чо делает-то? Текст кинь

переписать на Си хорошая идея, может есть другие варианты на
перл ? Подскажите пожлст какую-нибудь быструю ф-ю
для сравнения больших массивов слов ?
такой вариант очень медленный:


while($ha!=$#goodw)
    {
     $la=0;
     while($la!=$#goodw)
       {
      if($goodw[$ha]=~/$goodw[$la]/)
           {
            $cant_loop++;
            }
        $la++;
        }
      push(@ar,$goodw[$ha]);
      push(@ar,$cant_loop);
       }
  continue
        {
         $ha++;
         }

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

3. "RE: Как уменьшить время выполнения программ на perl?"
Сообщение от dawnshade emailИскать по авторуВ закладки on 14-Фев-03, 16:49  (MSK)

>      if($goodw[$ha]=~/$goodw[$la]/)

Если токо этот регэксп как-то упростить.

Еще вариант, что медленная скорость чтения из файла. Если операция регулярная и частая - есть смысл пользовать БД

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

4. "RE: Как уменьшить время выполнения программ на perl?"
Сообщение от konst emailИскать по авторуВ закладки on 14-Фев-03, 17:32  (MSK)
>
>>      if($goodw[$ha]=~/$goodw[$la]/)
>
>Если токо этот регэксп как-то упростить.
>
>Еще вариант, что медленная скорость чтения из файла. Если операция регулярная и
>частая - есть смысл пользовать БД
Еще вариант делать сравнение перед заполнением @goodw.
Не ужели такое сравнение $goodw[$ha]=~/$goodw[$la]/ дает нужный результат?

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

5. "RE: Как уменьшить время выполнения программ на perl?"
Сообщение от XMan Искать по авторуВ закладки on 14-Фев-03, 18:14  (MSK)
Хождение вокруг да около. Может задачу описать стоит ?

К примеру, у меня на перле файл метров 5 на аппарате Celeron-266/96 Mb RAM обрабатывается в течении доли секунды :)

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

7. "RE: Как уменьшить время выполнения программ на perl?"
Сообщение от RUSLAN Искать по авторуВ закладки on 14-Фев-03, 22:01  (MSK)
>Хождение вокруг да около. Может задачу описать стоит ?
>
>К примеру, у меня на перле файл метров 5 на аппарате Celeron-266/96
>Mb RAM обрабатывается в течении доли секунды :)

Вау, со вставками на асме код написан ? 8-)
Необходимо посчитать количество повторений каждого слова в тексте размером
от 90кб до 1 мб.  неболее чем за 2 сек.?


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

8. "RE: Как уменьшить время выполнения программ на perl?"
Сообщение от XMan Искать по авторуВ закладки on 15-Фев-03, 00:06  (MSK)
Ну что то  типа:


%hash=();
# подсчет
while (<>) {
@ar=split /\s+/;
foreach $key (@ar) {
$hash{$key}++;
};
};

# вывод хеша
print "Word\tCount";
foreach $word (keys  %hash) {
print "$word\t$hash{$word}";
};

На том же аппарате учетверенный файл лога ipchains (161660 Кб) если верить команде time:

real    0m0.800s
user    0m0.330s
sys     0m0.050s

:)

PS. Ну люблю я хеши за их удобство :)

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

9. "RE: Как уменьшить время выполнения программ на perl?"
Сообщение от RUSLAN Искать по авторуВ закладки on 15-Фев-03, 17:09  (MSK)

>PS. Ну люблю я хеши за их удобство :)


изменил все массивы на хэши, прога стала в 10 раз быстрее
работать. 0.77 мс.
Спасибо!
Ещё хотел спросить а как сравнивать ключи одного хеша с ключами другого
хеша ?

p.s теперь использую только хеши! ;-)

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

10. "RE: Как уменьшить время выполнения программ на perl?"
Сообщение от XMan Искать по авторуВ закладки on 15-Фев-03, 21:01  (MSK)
То есть ? Что значит сравнивать ключи хешей ?
  Рекомендовать в FAQ | Cообщить модератору | Наверх

11. "RE: Как уменьшить время выполнения программ на perl?"
Сообщение от RUSLAN Искать по авторуВ закладки on 16-Фев-03, 13:49  (MSK)
>То есть ? Что значит сравнивать ключи хешей ?

Есть первый хеш %hash1, c ключами в которых записаны ID, которые могут повторяться только по окончаниям например 34543zav,34544zav,34545lir,34546lir ....и.т.д, (окончания здесь zav и lir) а также есть ID в которых вообще окончаний нет типа 34543,34544....и.т.д.
И есть второй хеш %hash2 в ключах которого записаны окончания lir,zav,met,bal.... ну и т.д.
надо откидывать окончания из первого хеша, сравнивая с хешем %hash2 (что-бы знать какие окончания надо обрезать, так как окончания современем могут добавляться) и  помещать результат в третий хеш
%hash3 (тоесть ID без окончаний), и те ID у которых было обрезано окончания сравнивать с тем же хешем %hash1 (так как в нём могут быть ID без окончаний).

когда я сравниваю напрямую получается очень медленно типа:
.....

     while(($k1,$v1)=each %hash2)
       {
        $k_loop=0;
        while(($k2,$v2)=each %hash1)
             {
               if($k1=~/(.*)$k2/) # $k1 расширение
                   {
   $rez=$1; # $rez ID без окончания
                   $k_loop++;
      push(@ar,$rez); # массив куда заносим ID без окончаний
                   }
            

         };
        while(($k3,$v3)=each %hash1)
   {
  for (@ar)
                      {
if($k3=~/^($_)$/)
                            {
    $hash3{$k3}++;     
                           }
                        }
                    }

  .....

Есть ли более быстрый способ сравнения ? или что-то здесь упростить ?


p.s 34543zav,34544zav,34545lir,34546lir - это ID работников определённых цехов по окончаниям.(каждое окончание означает цех.)

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

12. "RE: Как уменьшить время выполнения программ на perl?"
Сообщение от XMan Искать по авторуВ закладки on 17-Фев-03, 02:19  (MSK)
Бррр... Ничего не понял... Ну или почти ничего :)
Все хеши заполнены ? То есть, если во всех трёх хешах ключам соответствуют не пустые значения, то можно сделать так:

-----------------------------------

foreach $k1 (keys %hash1) {
  # Убираем буквы все какие найдем. Результат в $k2
  ($k2 = $k1) =~ ( s/\D+//g );
  # Смотрим в %hash2
  if ($hash2{$k2}) {
    # Есть соответствие в хеше %hash2. Что-то делаем
    # Например, это. Типа смотрим, есть ли значени в %hash1
    # соответствующее $k1 без буковок
    if ($hash1{$k2}) {
      # Есть соответствие в хеше %hash1. Что-то делаем
      ...
    } else {
      # Нет соответствия в хеше %hash1. Что-то делаем
      ...
    };
    ...
  } else {
    # Нет соответствия в хеше %hash2. Делаем что-то другое
    ...
  };
};

-----------------------------------

Короче, ты подходишь к хешам, как к обычным массивам. Отсюда у тебя и тройная вложенность циклов. Как видишь, я обошелся одним циклом. Может я чего не понял ?

Теоретически, даже если есть ключи и пустые значения (типа "$hash{$key} eq '' " ), то все равно работать будет, только я не проверял.
Учти, что если у тебя в %hash1 есть ключ типа '123qwe456asd', то в $k2 будет значение '123456'

PS. Мой стиль тоже не блещет оптимизацией, как наследие от паскаля - уж больно многое я на нем мог сделать и на C переполз уже с устоявшимся стилем написания программ. Зато все просто и понятно. С этим согласился даже зубр написания всякой системной всячины под Linux :)

PS2. Если дашь всю информацию про исходные данные и нужном результате, то напишу весь скрипт.

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

13. "RE: Как уменьшить время выполнения программ на perl?"
Сообщение от RUSLAN Искать по авторуВ закладки on 17-Фев-03, 15:24  (MSK)
>
>foreach $k1 (keys %hash1) {
>  # Убираем буквы все какие найдем. Результат в $k2
>  ($k2 = $k1) =~ ( s/\D+//g );              # а если ID нечисловой ?
>  # Смотрим в %hash2
>  if ($hash2{$k2}) {
>    # Есть соответствие в хеше %hash2. Что-то делаем
>
>    # Например, это. Типа смотрим, есть ли значени
>в %hash1
>    # соответствующее $k1 без буковок
>    if ($hash1{$k2}) {
>      # Есть соответствие в хеше %hash1.
>Что-то делаем
>      ...
>    } else {
>      # Нет соответствия в хеше %hash1.
>Что-то делаем
>      ...
>    };
>    ...
>  } else {
>    # Нет соответствия в хеше %hash2. Делаем что-то
>другое
>    ...
>  };
>};
>
>-----------------------------------
>
>Короче, ты подходишь к хешам, как к обычным массивам. Отсюда у тебя
>и тройная вложенность циклов. Как видишь, я обошелся одним циклом. Может
>я чего не понял ?
>

       всё правильно ты понял ! это я туплю... :-)
       Я понял свою ошибку, до этого времени я подходил к проблеме
       как-бы глобально и далеко перешагнувши условие, а надо решать
       задание чисто по-условию ! :-) вот такая у мя философия. :-)


>Теоретически, даже если есть ключи и пустые значения (типа "$hash{$key} eq ''
>" ), то все равно работать будет, только я не проверял.
>
>Учти, что если у тебя в %hash1 есть ключ типа '123qwe456asd', то
>в $k2 будет значение '123456'
>
>PS. Мой стиль тоже не блещет оптимизацией, как наследие от паскаля -
>уж больно многое я на нем мог сделать и на C
>переполз уже с устоявшимся стилем написания программ. Зато все просто и
>понятно. С этим согласился даже зубр написания всякой системной всячины под
>Linux :)

     То что у тебя проги быстрые и легки в понимании я заметил,
     но невсегда универсальны, например ($k2 = $k1) =~ ( s/\D+//g );
     а если например это могут быть нечисловое значение в $k1 или в
     перемешку, тоесть abc123asd или abcasd, а надо выделить окончание ?
    Я думаю лучше писать скрипты с расчётом на будущее использование ! :-)


>
>PS2. Если дашь всю информацию про исходные данные и нужном результате, >то напишу весь скрипт.

        скрипт в принципе написан, есть пару проблем при сравнении
        строк через регексы, может ты сталкивался c таким деффектом,
        когда в строке есть символы типа( ? +), и компил перла выдаёт     ошибку при операциях
        например:

$string1="Hallo C++ , Perl Cool ! ";
$string2="C++";

while($string1=~m/($string2)/gc)
          {
....
            }

Есть идея добавлять перед каждым плюсом знак \ (тоесть
        $string1="Hallo C\+\+ , Perl Cool ! "; ) а потом уже сравнивать,
        или может есть более универсальный метод сравнения строк ?


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

14. "RE: Как уменьшить время выполнения программ на perl?"
Сообщение от XMan Искать по авторуВ закладки on 17-Фев-03, 18:28  (MSK)
> но невсегда универсальны, например ($k2 = $k1) =~ ( s/\D+//g );
> а если например это могут быть нечисловое значение в $k1 или в
> перемешку, тоесть abc123asd или abcasd, а надо выделить окончание
> ?

Слышь, ну ты бы выдал критерии определения окончания... :) И этот случай я оговорил отдельно.
А касательно универсальности - я как-то написал базу данных по оборудованию с использованием web-интерфейса и cgi на perl. Так там скрипт, который генерит страницу со списоком оборудования, иммет свой конфигурационный файл, так что я могу такие навороты делать... У меня там где-то и перекрестный запрос есть. Сам скрипт я не менял с момента запуска всей системы. Это порядка пары лет :)

> Есть идея добавлять перед каждым плюсом знак \ (тоесть

Подойдет, только тогда либо $string2="C\\+\\+"; либо $string2='C\+\+';
А в $string1 ничего не меняй.

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

6. "RE: Как уменьшить время выполнения программ на perl?"
Сообщение от RUSLAN Искать по авторуВ закладки on 14-Фев-03, 21:59  (MSK)
>>Еще вариант, что медленная скорость чтения из файла. Если операция регулярная и
>>частая - есть смысл пользовать БД
>Еще вариант делать сравнение перед заполнением @goodw.
>Не ужели такое сравнение $goodw[$ha]=~/$goodw[$la]/ дает нужный результат?

я решил вообще не заполнять массив, а присвоить весь текст
скаляру, и уже работать со скаляром, этот вариант выполняется порядком
меньше чем тот, но всё же очень долго 2.3 сек.  (PII~702/128Mb)
Может есть вариант как-то считать количество удалений в строке соответствующих определённому шаблону ?

$wodata - весь текст,
@goodw - тот же текст, но разбит по словам


foreach $wods(@goodw)
  {
   $wods=~s/^\s*//;
   $wods=~s/\s*$//;
   $i=0;
  while($wodata=~m/$wods/gs)
    {
    $i++;
    }
  push(@ar,$wods,$i);
  }

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


Удалить

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




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

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