Автор Тема: [Процессы] Как ускорить работу программы?  (Прочитано 6919 раз)

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

Оффлайн forfrends [?]

  • Новичок
  • *
  • Сообщений: 176
  • Репутация: 3
  • Пол: Мужской
    • Все для зароботка на автопилоте!
    • Награды
Всем добрый день!
Вот появилась у меня необходимость создать небольшую програмку-генератор набора символов. Длинна слова: 4 - 30 символов, всего используется 4 символа: пробел, скобки и умножение (*)
Все сделал по принципу:
Код: AutoIt [Выделить]
$Nabor = " ()*"
for $i1 = 1 to n; где n - это количество используемых символов
    for $i2 = 1 to n
        ...
            for $i30 = 1 to n
               ;генерация слова
               $slovo = StringMid($Nabor, $i1, 1) & StringMid($Nabor, $i2, 1) & ... & StringMid($Nabor, $i30, 1)
            next
        ...
    next
next

В результате программа работает ОООчень медлено. За 12 часов работы не прошло даже 10% комбинаций. Только что проверил - за 988.726 секунд (16 мин.) работы скрипта пройдено всего 130 000 комбинаций... это примерно 135 комбинаций в секунду. Мало...
Характеристики компа:
проц: AMD FX(tm)-6100 Six-Core Processor 6-ти ядерный на 3.9 Ггц       
Озу: 8 Гб
Windows 7 64x
Процессор загружен на 0-1%
Как ускорить работу скрипта? Может есть существенные альтернативы для For...Next? Можете что-то посоветовать? Как "загрузить" процессор по-полной?
Все для зароботка на автопилоте!
http://portal4you.ucoz.ru

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

[Процессы] Как ускорить работу программы?
« Отправлен: Февраль 19, 2014, 20:19:29 »

Оффлайн Afonichev [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 1535
  • Репутация: 408
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: [Процессы] Как ускорить работу программы?
« Ответ #1, Отправлен: Февраль 19, 2014, 20:56:45 »
Может так будет лучше!?

Код: AutoIt [Выделить]
MsgBox(0, '', Gen(' (*)', 30))

Func Gen($sSymbols, $iCount)

    Local $sResult


    For $i = 1 To $iCount
        $sResult &= StringMid($sSymbols, Random(1, StringLen($sSymbols), 1), 1)
    Next

    Return $sResult
EndFunc
 


Оффлайн forfrends [?]

  • Новичок
  • *
  • Сообщений: 176

  • Автор темы
  • Репутация: 3
  • Пол: Мужской
    • Все для зароботка на автопилоте!
    • Награды
Re: [Процессы] Как ускорить работу программы?
« Ответ #2, Отправлен: Февраль 19, 2014, 21:40:38 »
Viktor1703, такой вариант не подойдет из-за рандомности. Важно чтобы были испробованы все комбинации, а рандомность этого не дает - нетуверенности что нет повторений комбинаций и не пропущено ни одной комбинации.


Добавлено: Февраль 19, 2014, 21:42:20
firex, сам никогда не думал что до такого дойдет. На деле все эти вложенные циклы работают довольно медлено, да и в коде легко допустить опечатку из-за огромного числа вложений, похожих друг на друга.


Добавлено: Февраль 19, 2014, 21:51:01
Тут подумал что уходит лишнее время на постоянные StringMid, лучше брать данные из масива. Изменил код так:
Код: AutoIt [Выделить]
$Nabor = " ()*"
For $i = 1 To $n
    $f[$i] = StringMid($Nabor, $i, 1)
Next
for $i1 = 1 to $n; где $n - это количество используемых символов
    for $i2 = 1 to $n
        ...
            for $i30 = 1 to $n
               ;генерация слова
               $slovo = $f[$i1] & $f[$i2] & ... & $f[$i30]
            next
        ...
    next
next

В результате процессор загрузился до 3%, но скорость  генерации осталась той же - примерно 130-150 комбинаций в секунду.


Добавлено: Февраль 19, 2014, 22:12:53
Еще порылся в программе. Поодключал некоторые функции, в результате скорость возросла до 190 комбинаций в секунду... Но теперь нигде и никак не видно что программа работает (только в диспетчере задачь). :(
может это предел самого AutoItа?  :think:
« Последнее редактирование: Февраль 19, 2014, 22:34:48 от forfrends, Причина: Объединение сообщений »

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

Re: [Процессы] Как ускорить работу программы?
« Ответ #2 Отправлен: Февраль 19, 2014, 21:40:38 »

Оффлайн Afonichev [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 1535
  • Репутация: 408
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: [Процессы] Как ускорить работу программы?
« Ответ #3, Отправлен: Февраль 19, 2014, 22:22:10 »
Вообще вот все комбинации ( -1) мозги не работаю, выходит 192 комбинации, а надо 193, т.е. последняя комбинация возвращается *))) а нужно )))) нужно как - то ещё раз прокрутить цикл когда в $aComb[$i] будет цифра 4

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

$aRet = Gen(' (*)')

If IsArray($aRet) Then
    _ArrayDisplay($aRet)
EndIf

Func Gen($sSymbols)

    Local $sResult, $aComb[StringLen($sSymbols)], $aOut[1]

    For $i = 0 To Ubound($aComb) - 1
        $aComb[$i] = 1
    Next


    While 1
        If ($aComb[0] == StringLen($sSymbols)) Then
            ExitLoop
        EndIf

        For $i = 0 To Ubound($aComb) - 1

            $sResult &= StringMid($sSymbols, $aComb[$i], 1)

        Next

        $aOut[0] += 1

        _ArrayAdd($aOut, $sResult)

        $sResult = ''

        For $i = (Ubound($aComb) - 1) To 0 Step -1
            $aComb[$i] += 1
            If $aComb[$i] > StringLen($sSymbols) Then
                $aComb[$i] = 1
            Else
                ExitLoop
            EndIf
        Next
    Wend


    Return $aOut
EndFunc
 



Добавлено: Февраль 19, 2014, 22:33:34
Пришлось по извращаться....

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

$aRet = Gen(' (*)')

If IsArray($aRet) Then
    _ArrayDisplay($aRet)
EndIf

Func Gen($sSymbols)

    Local $sResult, $aComb[StringLen($sSymbols)], $aOut[1]

    For $i = 0 To Ubound($aComb) - 1
        $aComb[$i] = 1
    Next

    While 1
        If ($aComb[0] >= StringLen($sSymbols)) Then
           
            For $i = 0 To Ubound($aComb) - 1
                $sResult &= StringMid($sSymbols, StringLen($sSymbols), 1)
            Next

            $aOut[0] += 1

            _ArrayAdd($aOut, $sResult)

            ExitLoop
        EndIf

        For $i = 0 To Ubound($aComb) - 1
            $sResult &= StringMid($sSymbols, $aComb[$i], 1)
        Next

        $aOut[0] += 1

        _ArrayAdd($aOut, $sResult)

        $sResult = ''

        For $i = (Ubound($aComb) - 1) To 0 Step -1
            $aComb[$i] += 1
            If $aComb[$i] > StringLen($sSymbols) Then
                $aComb[$i] = 1
            Else
                ExitLoop
            EndIf
        Next
    Wend

    Return $aOut
EndFunc
 

« Последнее редактирование: Февраль 19, 2014, 22:37:16 от Viktor1703, Причина: Объединение сообщений »

Оффлайн forfrends [?]

  • Новичок
  • *
  • Сообщений: 176

  • Автор темы
  • Репутация: 3
  • Пол: Мужской
    • Все для зароботка на автопилоте!
    • Награды
Re: [Процессы] Как ускорить работу программы?
« Ответ #4, Отправлен: Февраль 19, 2014, 22:37:44 »
Viktor1703, хороший пример, только длина генерируемого слова должна быть 30 символов. Как в первом вашем примере.

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

Re: [Процессы] Как ускорить работу программы?
« Ответ #4 Отправлен: Февраль 19, 2014, 22:37:44 »

Оффлайн Afonichev [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 1535
  • Репутация: 408
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: [Процессы] Как ускорить работу программы?
« Ответ #5, Отправлен: Февраль 19, 2014, 22:46:22 »
forfrends

я выставил размер 5 [количество комбинаций: 2501] и у меня появились повторяющиеся комбинации, я полагаю из-за того что длина слова не должна быть больше набора символов иначе будут повторения..

Оффлайн winstan [?]

  • Продвинутый
  • ***
  • Сообщений: 406
  • Репутация: 78
  • Пол: Мужской
  • Эксплотатор)
    • Награды
  • Версия AutoIt: 3.3.12.0
Re: [Процессы] Как ускорить работу программы?
« Ответ #6, Отправлен: Февраль 19, 2014, 22:49:57 »
Viktor1703
forfrends
Бедный мой мозг от ваших кодов  :o
Помог мой мост? Жми "Полезное сообщение")

я полный "чайник" , но с другой стороный-не пустой.
Каму не трудно кликните по банару(это поднимит мой кирпичек на стене ников)

Оффлайн Afonichev [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 1535
  • Репутация: 408
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: [Процессы] Как ускорить работу программы?
« Ответ #7, Отправлен: Февраль 19, 2014, 22:52:31 »
winstan

 ;D

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

Re: [Процессы] Как ускорить работу программы?
« Ответ #7 Отправлен: Февраль 19, 2014, 22:52:31 »

Оффлайн inx [?]

  • Новичок
  • *
  • Сообщений: 43
  • Репутация: 12
    • Награды
Re: [Процессы] Как ускорить работу программы?
« Ответ #8, Отправлен: Февраль 19, 2014, 23:07:09 »
Не подойдет?  :)

Код: AutoIt [Выделить]
Local $file = FileOpen("combinations.txt", 1)
$Letters = StringSplit(" ,(,),*", ",")
Combinator("", 30)
Func Combinator($Str, $MaxLength)
Dim $i
    if StringLen($Str) = $MaxLength Then
        FileWrite($file, $Str & @CRLF)
        Return
    EndIf
    For $i = 1 to $Letters[0]
        Combinator($Str & $Letters[$i], $MaxLength)
    Next
EndFunc


Для 4-30
Код: AutoIt [Выделить]
Local $file = FileOpen("combinations.txt", 1)
$Letters = StringSplit(" ,(,),*", ",")
For $n = 4 to 30
    Combinator("", $n)
Next
Func Combinator($Str, $MaxLength)
Dim $i
    if StringLen($Str) = $MaxLength Then
        FileWrite($file, $Str & @CRLF)
        Return
    EndIf
    For $i = 1 to $Letters[0]
        Combinator($Str & $Letters[$i], $MaxLength)
    Next
EndFunc

« Последнее редактирование: Февраль 19, 2014, 23:41:43 от inx »

Оффлайн forfrends [?]

  • Новичок
  • *
  • Сообщений: 176

  • Автор темы
  • Репутация: 3
  • Пол: Мужской
    • Все для зароботка на автопилоте!
    • Награды
Re: [Процессы] Как ускорить работу программы?
« Ответ #9, Отправлен: Февраль 19, 2014, 23:24:46 »
Цитировать
длина слова не должна быть больше набора символов иначе будут повторения..
Не совсем так, похожие комбинации будут, а вот одинаковые нет. Пример комбинаций из 2-х символов "+" и "-":
(нажмите для показа/скрытия)

Оффлайн firex [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 943
  • Репутация: 203
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.x.x
« Последнее редактирование: Февраль 20, 2014, 18:08:01 от firex »

Оффлайн forfrends [?]

  • Новичок
  • *
  • Сообщений: 176

  • Автор темы
  • Репутация: 3
  • Пол: Мужской
    • Все для зароботка на автопилоте!
    • Награды
Re: [Процессы] Как ускорить работу программы?
« Ответ #11, Отправлен: Февраль 19, 2014, 23:40:13 »
firex, я так и сделал  :P


Добавлено: Февраль 19, 2014, 23:43:26
inx, ваш вариант однозначно лучше всех предыдущих вариантов - за 15 секунд забил файл комбинациями на целых 250 мегабайт! Нотпад++ отказыватся открывать :)
Буду пробовать ваш вариант.
Только один вопрос: зачем Dim $i вызывать в функции? Не проще ли один раз в начале программы? Или таким способом переменная обнуляется?


Добавлено: Февраль 20, 2014, 00:03:09
inx, спасибо, понял. А с вложением цикла это просто гениальная идея! Коротко, просто и быстродействено :)
« Последнее редактирование: Февраль 20, 2014, 00:03:09 от forfrends, Причина: Объединение сообщений »

Оффлайн sims [?]

  • Осваивающий
  • **
  • Сообщений: 184
  • Репутация: 24
  • Пол: Мужской
    • Награды
Re: [Процессы] Как ускорить работу программы?
« Ответ #12, Отправлен: Февраль 20, 2014, 00:16:56 »
AutoIt интерпретируемый ЯП и довольно медленно работающий. Он не предназначен для скоростных вычислений. Если нужна скорость, то лучше компилировать программу, притом желательно в натив, а не в байт-код. Чтобы получить максимальное быстродействие, нужно работать со строками как с массивом символов.

Мне удалось добиться генерации больше 2 миллионов комбинаций в секунду. И это на одном ядре (которое при этом загружено по полной). Если задачу разделить на несколько потоков, а она хорошо делится, то можно добиться еще большей производительности.

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

Оффлайн winstan [?]

  • Продвинутый
  • ***
  • Сообщений: 406
  • Репутация: 78
  • Пол: Мужской
  • Эксплотатор)
    • Награды
  • Версия AutoIt: 3.3.12.0
Re: [Процессы] Как ускорить работу программы?
« Ответ #13, Отправлен: Февраль 20, 2014, 01:03:34 »
sims  [?]
Цитировать
добиться генерации больше 2 миллионов комбинаций в секунду
Не плохо, у меня получалось добиваться только около 600-800 тыс комбинаций в секунду, длинной 16 символов при базе в 62 символа.
 :whistle: думаю не трудно догодаться для чего я делал, вот тольк интернет не позвлял всёравно столько запросов отправлять

Оффлайн sims [?]

  • Осваивающий
  • **
  • Сообщений: 184
  • Репутация: 24
  • Пол: Мужской
    • Награды
Re: [Процессы] Как ускорить работу программы?
« Ответ #14, Отправлен: Февраль 20, 2014, 01:13:20 »
Можете попробовать (файл внизу поста).
После запуска рядом с прогой будет создан текстовый файл GenTest.txt в который запишется результат. На диске должно быть много свободного места. Прога пишет примерно 8 ГБ в минуту при длине 30 символов.
В консоли отображаются текущие данные процесса выполнения. Для закрытия проги, закройте консоль.

http://rghost.ru/52539725

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

Re: [Процессы] Как ускорить работу программы?
« Ответ #14 Отправлен: Февраль 20, 2014, 01:13:20 »

 

Похожие темы

  Тема / Автор Ответов Последний ответ
14 Ответов
6670 Просмотров
Последний ответ Август 29, 2010, 13:33:58
от CreatoR
1 Ответов
2596 Просмотров
Последний ответ Февраль 28, 2011, 22:34:30
от Arei
20 Ответов
6029 Просмотров
Последний ответ Февраль 04, 2012, 19:23:08
от Leanna
4 Ответов
2242 Просмотров
Последний ответ Июль 29, 2012, 11:10:07
от joiner
23 Ответов
7665 Просмотров
Последний ответ Март 21, 2013, 11:11:37
от madmasles
4 Ответов
4977 Просмотров
Последний ответ Август 18, 2013, 09:19:10
от Redline
0 Ответов
1197 Просмотров
Последний ответ Февраль 25, 2014, 10:28:18
от StarWash
6 Ответов
2439 Просмотров
Последний ответ Февраль 05, 2015, 11:44:42
от darkwhite
5 Ответов
428 Просмотров
Последний ответ Май 08, 2019, 21:48:27
от Prog
10 Ответов
492 Просмотров
Последний ответ Май 13, 2019, 00:03:28
от Tosyk