Русское сообщество AutoIt

  • Июнь 18, 2013, 09:06:42 *
  • Добро пожаловать, Гость
Пожалуйста, войдите или зарегистрируйтесь.

Войти
Расширенный поиск  

Новости:


Последняя финальная версия AutoIt: 3.3.8.1 (Скачать)
Последняя Beta версия AutoIt: 3.3.9.4 (Скачать)

Реклама

Автор Тема: AutoIt 3.3.6.0 - тормозят регулярные выражения  (Прочитано 3114 раз)

0 Пользователей и 1 Гость смотрят эту тему.

Suppir [?]

Запускаю свою программу TrayGREP - а она стала в 2 - 3 раза медленней работать, чем в версии 3.3.4.0. Программа активно использует функции:
Код: AutoIt [Выделить]

Кто столкнулся с тормозами регекспов в новой версии - в чем здесь может быть дело?
« Последнее редактирование: Март 23, 2010, 11:56:37 от Suppir »



  Записан

VitAl2013 [?]

  • Гость
точно 3.6.6.0?




  Записан

asdf8 [?]

  • Скриптер
  • ****
  • Репутация: 119
  • Offline Offline
  • Сообщений: 421
  • Версия AutoIt: 3.3.8.0
    • Награды
Проверил StringRegExp от версии 3.3 до 3.3.6
Действительно есть замедление работы от версии к версии.
Получилось, что 3.3.6 в среднем на 17% медленнее, чем 3.3

А StringReplace - наоборот, стала работать на пару процентов быстрее
« Последнее редактирование: Март 23, 2010, 11:38:48 от asdf8 »



  Записан

Suppir [?]

  • Продвинутый
  • ***

  • Автор темы
  • Репутация: 52
  • Offline Offline
  • Сообщений: 813
    • Награды
Имеется в виду свежая версия 3.3.6.0.

В моем приложении примерно 95% процессорного времени тратится на обработку текста регулярными выражениями. Замедление в несколько раз по сравнению с версией 3.3.4.0 :(
« Последнее редактирование: Март 23, 2010, 11:55:25 от Suppir »



  Записан

asdf8 [?]

  • Скриптер
  • ****
  • Репутация: 119
  • Offline Offline
  • Сообщений: 421
  • Версия AutoIt: 3.3.8.0
    • Награды
в чем здесь может быть дело?

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




  Записан

Suppir [?]

  • Продвинутый
  • ***

  • Автор темы
  • Репутация: 52
  • Offline Offline
  • Сообщений: 813
    • Награды
Код программы:

Код: AutoIt [Выделить]
#Include <Misc.au3>

;~ Предотвращаем запуск двух копий программы
if _Singleton("test",1) = 0 Then
    TrayTip ("AutoIt", "TreyGREP уже запущен", 1)
    sleep(1000)
    TrayTip("clears any tray tip","",0)
    Exit
EndIf


;~ Добавляем пользовательское меню в трей
TraySetState ( 1 )
Opt("TrayMenuMode", 1)

;~ Устанавливаем хоткеи. Так как раскладка может быть и русской и английской, дублируем хоткеи для обеих раскладок
HotKeySet("^x", "_Replace")
HotKeySet("^ч", "_Replace")
HotKeySet("^+x", "_Exit")
HotKeySet("^+ч", "_Exit")

;~ Объявление переменных и массивов
Global $i, $a, $Text
Dim $Search[1000][2]
Dim $Matches, $Splited

;~ Путь к ini-файлу
$IniFile = @ScriptDir & "\" & "TrayGREP.ini"

;~ Создаем меню в трее
$Edit = TrayCreateItem("Редактировать список замен")
$Exit = TrayCreateItem("Выход")

;~ Если ini не найден...
if not FileExists($IniFile) Then
    TrayTip ("AutoIt", "Не могу найти файл ""TrayGREP.ini""", 1)
    sleep(2000)
    TrayTip("clears any tray tip","",0)
    Exit
Else   
   
    $in = FileOpen("TrayGREP.ini", 0)
    $line = FileReadLine($in, 1)
    if $line <> "TrayGREP v.1.0. Автор идеи и разработчик - Suppir." Then
        TrayTip ("AutoIt", "Информация о разработчике была повреждена", 1)
        sleep(3000)
        TrayTip("clears any tray tip","",0)
        TrayTip ("AutoIt", "Восстановите информацию или скачайте утилиту заново", 1)
        sleep(3000)
        TrayTip("clears any tray tip","",0)
        Exit
    EndIf  
EndIf  

;~ Подсказки в трее пользователю
TrayTip ("AutoIt", "TrayGREP запущен", 1)
sleep(2000)
;~ Подсказки внеобходимо убирать вручную
TrayTip("clears any tray tip","",0)

;~ Основной цикл программы
While 1
    Switch TrayGetMsg()
   
;~  Если выбрали "редактировать список замен"...
    Case $Edit
;~      То открываем ini блокнотом. Здесь может быть проблема, если для открывания ini назначена другая программа
        ShellExecute ($IniFile)
        TrayItemSetState ( $Edit, 4 )
;~  Если выбрали "выйти", завершаем программу
    Case $Exit
        TrayItemSetState ( $Edit, 4 )
        _Exit()
    EndSwitch
WEnd

;~ Функция завершения программы
Func _Exit()
   
    TrayTip ("AutoIt", "Завершение работы TrayGREP", 1)
    Sleep(1000)
    Exit
   
EndFunc


;~ Функция замены текста
Func _Replace()
   
;~  Если в буфере обмена ничего нет, то давать предупреждение
    if ClipGet() = "" Then
        TrayTip ("AutoIt", "Буфер пустой!", 1)
        sleep(1000)
        TrayTip("clears any tray tip","",0)

    Else
;~      Считываем ini-файл. Здесь может быть проблема. Если запустить программу, а потом удалить ini, то функция не будет работать
        $in = FileOpen("TrayGREP.ini", 0)
        while 1
;~          Читаем строки в ini последовательно
            local $i
            $line = FileReadLine($in)
            If @error = -1 Then ExitLoop
           
;~          Если находим строку "найти то-то", то запоминаем регексп в двумерный массив $Search[][]
;~          Левый элемент массива равен "найти", правый - "заменить"
            $Matches = StringRegExp($line, "^Найти:(.+)", 1)  
            If @error = 0 Then
                $Search[$i][0] = $Matches[0]
                ContinueLoop
            EndIf  
       
;~          Если находим строку "Заменить на:" после которой сразу конец строки, то задаем значение переменной $Search[$i][1] = "".
;~          Если этого не делать, то поиск в таких случаях не будет работать.
            $Matches = StringRegExp($line, "^Заменить на:$", 1)
            If @error = 0 Then
                $Search[$i][1] = ""
                $i += 1
                ContinueLoop
            EndIf
       
;~          Запоминаем переменную замены
            $Matches = StringRegExp($line, "^Заменить на:(.+)", 1)
            If @error = 0 Then
                $Search[$i][1] = $Matches[0]
                $i += 1
                ContinueLoop
            EndIf
        wend   


        TrayTip ("AutoIt", "Произвожу замену...", 1)
;~      Берем строку из буфера
        $Text = ClipGet()
;~      И разрезаем ее в массив по символам конца строки. Если этого не делать, то замена будет производиться только для первого встреченного абзаца.
        $Splited = StringSplit($Text, @CRLF, 1)
        $Text = ""
       
;~      На каждую строку в массиве $Splited применяем регулярные выражения из массива $Search
        For $x = 1 to UBound($Splited)-1
            for $i = 0 to UBound($Search) - 1
                    $Splited[$x] = StringRegExpReplace($Splited[$x], $Search[$i][0], $Search[$i][1])
            Next
;~          После чего склеиваем строки обратно 
            if $Text = "" Then
                $Text = $Splited[$x]
            Else
                $Text = $Text & @CRLF & $Splited[$x]
            EndIf
        Next

;~      И записываем результат в буфер обмена
        ClipPut($Text)
        TrayTip ("AutoIt", "Замена произведена", 1)
        sleep(1000)
        TrayTip("clears any tray tip","",0)

    EndIf
EndFunc


;~ необходимо добавить функции
;~ 1) объявление вспомогательных переменных в ini
;~ 2) поддержка таблиц MS Word в буфере
 




Примеры регулярных выражений из ini-файла:

Найти:(№|N)[ °]*(\d)
Заменить на:N $2

Найти: +
Заменить на:

Найти:(^)\s+
Заменить на:$1

Найти:\s+$
Заменить на:

Найти:^\s+$
Заменить на:

Найти:(\d)г\.
Заменить на:$1 г.

Найти:(\d)г
Заменить на:$1 г.

Найти:(\d)года
Заменить на:$1 года

Найти: (ул|г|пос|пер)\.(\S)
Заменить на: $1. $2

Найти: (п|ч|ст)\.(\d)
Заменить на: $1. $2

Найти:N°
Заменить на:N

Найти:(\d)м
Заменить на:$1 м

Найти:(\d)м\.
Заменить на:$1 м.

Найти:""
Заменить на:"

Найти:—|–
Заменить на:-

Найти:^\s+(\d)
Заменить на:$1

Найти: (\d{4})-(\d{4}) г
Заменить на: $1 - $2 г

Найти:(\d+)\.(\D)
Заменить на:$1. $2

Найти:п р и к а з ы в а ю
Заменить на:приказываю

Найти:П Р И К А З Ы В А Ю
Заменить на:приказываю
« Последнее редактирование: Март 23, 2010, 12:46:43 от Suppir »



  Записан

asdf8 [?]

  • Скриптер
  • ****
  • Репутация: 119
  • Offline Offline
  • Сообщений: 421
  • Версия AutoIt: 3.3.8.0
    • Награды
Suppir попробуй заменить функцию:

Код: AutoIt [Выделить]
;~ Функция замены текста
Func _Replace()
;~  Если в буфере обмена ничего нет, то давать предупреждение
    if ClipGet() = "" Or Not FileExists(@ScriptDir & "\" & "TrayGREP.ini") Then
        TrayTip ("AutoIt", "Буфер пустой!", 1)
        sleep(1000)
        TrayTip("clears any tray tip","",0)

    Else
;~      Считываем ini-файл. Здесь может быть проблема. Если запустить программу, а потом удалить ini, то функция не будет работать
        $in = FileRead("TrayGREP.ini")
        $patern = '(Найти:.+?[\r\n]+Заменить на:[^\r\n]*)'
        $Search = StringRegExp($in, $patern, 3)
;~      Exit
        TrayTip ("AutoIt", "Произвожу замену...", 1)
;~      Берем строку из буфера
        $Text = ClipGet()
        If $Text Then
            If IsArray($Search) Then
                $patern = 'Найти:(.+?)[\r\n]+Заменить на:(.*)'
                For $i = 0 To UBound($Search) - 1
                    $sSearch = StringRegExpReplace($Search[$i], $patern, '\1')
                    $sReplace = StringRegExpReplace($Search[$i], $patern, '\2')
                    ConsoleWrite('!>' & $sSearch & '-->' & $sReplace & @LF)
                    $Text = StringRegExpReplace($Text, '(?m)' & $sSearch, $sReplace)
                Next
;~          И записываем результат в буфер обмена
            ClipPut($Text)
            TrayTip ("AutoIt", "Замена произведена", 1)
            sleep(1000)
            TrayTip("clears any tray tip","",0)
            EndIf
        EndIf
    EndIf
EndFunc
 


Как будет по скорости?

И еще: в коде несколько раз встречается FileOpen и нету FileClose, как раз, между версиями менялась работа с файлами, мне кажется из-за этого и проблемы.
« Последнее редактирование: Март 23, 2010, 14:43:02 от asdf8 »



  Записан

Suppir [?]

  • Продвинутый
  • ***

  • Автор темы
  • Репутация: 52
  • Offline Offline
  • Сообщений: 813
    • Награды
Попробую на домашнем компе (т.к. уже снес версию 3.3.6.0). Позже отпишусь.




  Записан

Suppir [?]

  • Продвинутый
  • ***

  • Автор темы
  • Репутация: 52
  • Offline Offline
  • Сообщений: 813
    • Награды
Быстро работает, спасибо!




  Записан

Suppir [?]

  • Продвинутый
  • ***

  • Автор темы
  • Репутация: 52
  • Offline Offline
  • Сообщений: 813
    • Награды
Re: AutoIt 3.3.6.0 - тормозят регулярные выражения
« Ответ #9, Отправлен: Апрель 01, 2010, 16:16:14 »
Две проблемы:
1) в измененном тексте теперь вместо разделителей строк "\n" мягкие переносы строк;
2) если в тексте были пустые строки, то они исчезли.




  Записан

asdf8 [?]

  • Скриптер
  • ****
  • Репутация: 119
  • Offline Offline
  • Сообщений: 421
  • Версия AutoIt: 3.3.8.0
    • Награды
Re: AutoIt 3.3.6.0 - тормозят регулярные выражения
« Ответ #10, Отправлен: Апрель 01, 2010, 16:51:43 »
Цитата
Две проблемы

надо подкорректировать регулярные выражения в ini-файле, ^ и $ в моем примере обозначают "\n".
Например выражение  равно "\n\s+\n", а "\s" включает в себя и "\r" - вот и получаются мягкие переносы строк и удаление пустых строк ("\n\s+\n" включает "\n\r\n"). Если заменить "^\s+$" на Найти:"(^)[\t ]+([\r\n])" Заменить на:"\1\2" будет работать нормально. Ну и остальные регекспы проверить.




  Записан

Suppir [?]

  • Продвинутый
  • ***

  • Автор темы
  • Репутация: 52
  • Offline Offline
  • Сообщений: 813
    • Награды
Re: AutoIt 3.3.6.0 - тормозят регулярные выражения
« Ответ #11, Отправлен: Апрель 01, 2010, 17:48:18 »
ясно...




  Записан
 


Похожие темы
Тема Автор Ответов Просмотров Последний ответ
Разделение текста до и после пустой строки (регулярные выражения)
Регулярные выражения и прочее
Latoid 3 1734 Последний ответ Декабрь 10, 2009, 13:52:38
от Latoid
Регулярные выражения - освоение
Регулярные выражения и прочее
aranea 12 2519 Последний ответ Ноябрь 11, 2010, 21:50:18
от dwerf
Полезные регулярные выражения для SciTE
Инструменты и справка по AutoIt
CreatoR 9 4951 Последний ответ Январь 23, 2012, 13:21:22
от CreatoR
Регулярные выражения: Как убрать все что вне круглых скобок?
Регулярные выражения и прочее
Kalisnik 2 2109 Последний ответ Февраль 11, 2011, 20:26:34
от CreatoR
 Закреплено  Частоиспользуемые выражения / шаблоны
Регулярные выражения и прочее
CreatoR 0 5434 Последний ответ Февраль 13, 2011, 00:16:11
от CreatoR
 Закреплено  Правила раздела (Регулярные выражения и прочее)
Регулярные выражения и прочее
CreatoR 0 1520 Последний ответ Февраль 13, 2011, 00:26:49
от CreatoR
Перенесено: Полезные регулярные выражения для SciTE
Общение
CreatoR 0 932 Последний ответ Апрель 02, 2011, 14:23:51
от CreatoR
Вычисление выражения, полученого со страницы в браузере
Стол заказов
-ZIG-ZAG- 18 2592 Последний ответ Декабрь 12, 2011, 09:01:51
от Kaster
[Данные, строки] Сортировка чисел по условию через регулярные выражения
Регулярные выражения и прочее
ViktorSPB 36 3112 Последний ответ Июль 12, 2012, 23:22:05
от CreatoR
Можно ли и как вернуть все найденные регулярные выражения?
Регулярные выражения и прочее
PACHOM 3 157 Последний ответ Июнь 09, 2013, 21:51:04
от PACHOM


Реклама