Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обсудим как ускорить алгоритм? Замена регуляркой, много замены 
:(
    Опции темы
MakTpaxep
  Дата 17.6.2011, 10:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 25.11.2010

Репутация: нет
Всего: нет



Есть таблица соответствий в файле - строка-строка.
Получается хэш около 1000 элементов.
Нужно заменить в исходном файле все эти строки на соответствующие (для простоты предположим что в файле просто слова).

Мой код работает неприлично долго. 
В каждой строке исходного файла пробегает по всем ключам и если находит заменяет их.
Код

foreach (@data)
{
   foreach my $key (keys %hash)
   {
      my $h=$hash{$key};
      s!\b$key\b!$h!g;
   }
}


Господа, какие есть идеи по ускорению проги?

Добавлю:
Файл большой, строки тоже бывают по несколько тысяч.

Это сообщение отредактировал(а) MakTpaxep - 17.6.2011, 10:32
PM MAIL   Вверх
Suppir
Дата 17.6.2011, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 588
Регистрация: 20.4.2009

Репутация: нет
Всего: нет



Если файл не слишком большой, то, возможно, мультистрочный поиск (по всему файлу целиком) будет быстрее. Т.е. не нужно для каждой строки перебирать библиотеку замен. 



Это сообщение отредактировал(а) Suppir - 17.6.2011, 10:26
PM MAIL   Вверх
Logo
Дата 17.6.2011, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 694
Регистрация: 22.7.2008

Репутация: 3
Всего: 10



Однако, судя по коду, файл полностью посещается в память?
PM MAIL   Вверх
arto
Дата 17.6.2011, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



# perl -MBenchmark=timethese -e '%h = map { $_ => "aa$_" } 1024; @data = 0..10_000; $re = join "|", keys %h; timethese ($ARGV[0], { mak => sub { foreach (@data) { foreach my $k (keys %h) { my $h = $h{$k}; s#\b$k\b#$h#g } } }, arto => sub { foreach (@data) { s#\b($re)\b#$h{$1}#go } } })' 1000
Benchmark: timing 1000 iterations of arto, mak...
      arto:  2 wallclock secs ( 1.82 usr +  0.01 sys =  1.83 CPU) @ 546.45/s (n=1000)
       mak: 14 wallclock secs (12.78 usr +  0.00 sys = 12.78 CPU) @ 78.25/s (n=1000)

PM MAIL ICQ   Вверх
MakTpaxep
Дата 17.6.2011, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 25.11.2010

Репутация: нет
Всего: нет



Цитата(arto @  17.6.2011,  11:03 Найти цитируемый пост)
# perl -MBenchmark=timethese -e '%h = map { $_ => "aa$_" } 1024; @data = 0..10_000; $re = join "|", keys %h; timethese ($ARGV[0], { mak => sub { foreach (@data) { foreach my $k (keys %h) { my $h = $h{$k}; s#\b$k\b#$h#g } } }, arto => sub { foreach (@data) { s#\b($re)\b#$h{$1}#go } } })' 1000Benchmark: timing 1000 iterations of arto, mak...      arto:  2 wallclock secs ( 1.82 usr +  0.01 sys =  1.83 CPU) @ 546.45/s (n=1000)       mak: 14 wallclock secs (12.78 usr +  0.00 sys = 12.78 CPU) @ 78.25/s (n=1000)

А мысль не дурна, спасибо smile
Только вот если найдёт слово, которого нету в хэше, то боюсь думать что он подставит.
Можно как-нибудь прямо в рег вставить проверку, если вам не трудно? 
Я реги ещё не настолько изучил, чтобы код внутри писать (наверное самое время).

Цитата(Logo @  17.6.2011,  10:59 Найти цитируемый пост)
Однако, судя по коду, файл полностью посещается в память?

Конечно, а как иначе?

Цитата

Если файл не слишком большой, то, возможно, мультистрочный поиск (по всему файлу целиком) будет быстрее. Т.е. не нужно для каждой строки перебирать библиотеку замен. 

Идею понял, можно просто поменять циклы местами. Но таки самая большая потеря скорости точно не здесь.

Это сообщение отредактировал(а) MakTpaxep - 17.6.2011, 11:22
PM MAIL   Вверх
arto
Дата 17.6.2011, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



а как его найдут?
PM MAIL ICQ   Вверх
MakTpaxep
Дата 17.6.2011, 11:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 25.11.2010

Репутация: нет
Всего: нет



А ну да - не найдут. Это я стормозил.
А вот если вместо ($re) было бы (\w+), то было бы ещё быстрее, только тогда надо не производить замен если такого ключа нету.

Это сообщение отредактировал(а) MakTpaxep - 17.6.2011, 11:38
PM MAIL   Вверх
arto
Дата 17.6.2011, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



ну если вы уверены, что у вас там класс \w+, то s#\w+#$h{$&}||''#ge
PM MAIL ICQ   Вверх
MakTpaxep
Дата 17.6.2011, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 25.11.2010

Репутация: нет
Всего: нет



Спасибо огромное, я посмотрю что значат эти две палочки=)
Ещё вопрос по этому регу s#\b($re)\b#$h{$1}#go 
Тут ведь переменные есть, какое тогда значение имеет модификатор "o"?
Я токо в рунете находил, а решил на perldoc глянуть, так нету его О_о 
http://perldoc.perl.org/perlre.html

Это сообщение отредактировал(а) MakTpaxep - 17.6.2011, 11:54
PM MAIL   Вверх
arto
Дата 17.6.2011, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



perldoc perlop на предмет Regexp Quote-Like Operators
PM MAIL ICQ   Вверх
MakTpaxep
Дата 17.6.2011, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 25.11.2010

Репутация: нет
Всего: нет



Да всё проще чем я думал=)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0480 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.