Print This Post Пишем простой асинхронный парсер

Четверг, 23. Февраль 2012
Раздел: Perl, автор:

Многие разработчики типового говнософта, ориентированного на работу с вебом, зачастую используют потоки для того, чтобы получить выигрыш в скорости. Данный подход, конечно, обладает своими плюсами, но все же не является оптимальным, например, с точки зрения потребляемых ресурсов системы (особенно когда речь идет о потребителях, любящих ставить сразу "тыщу потоков").
Альтернативным и общеизвестным способом ускорения работы софта является асинхронная модель, то есть модель, при которой все вызовы методов являются неблокирующими. В данной статье я рассмотрю простой пример, который будет использовать асинхронные веб-запросы.
В качестве примера будет написан парсер идентификаторов приложений с Android Market, который пригодится в готовящейся статье, посвященной добычи трафика с маркета. Для простоты будем использовать модуль AnyEvent, он упрощает реализацию асинхронной событийной модели. Итак, приступим.

Для начала прагмы, необходимые инклюды и переменные:

В целом код довольно небольшой, поэтому я не буду излишне фрагментировать его, а изложу основную часть одним куском и прокомментирую.

Теперь сравним вышеприведенный скрипт со скриптом, который выполняет ту же самую работу, но опирается на потоки. Вот код этого скрипта:

Скорость работы скриптов примерно одинакова, и там и там идет одновременное выполнение 15 веб-запросов, однако, если обратить внимание на потребляемую память и нагрузку на процессор, то мы увидим явное преимущество у первого скрипта. У меня количество потребляемой памяти для асинхронного варианта составляло ~ 12 мегабайт, а в случае с потоками оно увеличилось до ~ 53 мегабайт (хотя прожорливость perl + pthreads под win* - известная печалька).
Но даже если абстрагироваться от языка программирования и использовать WinAPI для работы с потоками, то можно увидеть, что при большом количестве потоков (конечно, ведь чем больше потоков, тем круче и быстрее (с) дефолт логика) нагрузка на процессор вырастет несоизмеримо по сравнению с асинхронной моделью.

В общем, асинхронная модель зачастую является более предпочтительной, но иногда требует нетривиального планирования алгоритма работы программы, например, когда есть необходимость совершать множество зависящих друг от друга запросов и менять логику поведения в зависимости от результатов, полученных на предыдущих стадиях.

Скрипты из статьи: скачать

 Обсудить на форуме


Получать обновления на почту:     

Комментариев: 17 к “Пишем простой асинхронный парсер”


  1. flisk :

    Спасибо за интересный пример, давно хотел попробовать поработать с AnyEvent.

    [Ответить]


  2. Рита :

    >конечно, ведь чем больше потоков, тем круче и быстрее (с) дефолт логика
    Дефолт сарказм обладателя полуядерного ЦП

    [Ответить]

    dx:

    Риточка, Вы не правы. Если Вы поставите 1000 потоков на четырехядерной машине, Вы уже увидите, что приличная часть процессорного времени расходуется на переключение их контекстов. Если речь идет о Windows и перле, то вы и 100 потоков с трудом поставите, так как у вас оперативной памяти несколько гигабайт отожрется при этом. А если Вы поддерживаете мысль "1000 потоков - это охуенно", то советуем Вам немного пересмотреть свою логику. Хотя, вероятно, Вы просто can't into asynchronous.

    [Ответить]

    Рита:

    Вот она система моей мечты, Windows, конечно! Весь софт серьезные дядьки - спамеры веба пишут под неё, ага.

    [Ответить]

    Дядька-спамер:

    Серьезные дядьки-спамеры по социалочкам голосуют за Windows из-за наличия кучи дешевых дедиков! Windows - выбор профессионала.

    mr.The:

    >Дефолт сарказм обладателя полуядерного ЦП
    дефолт сарказм владельца мощного пк купленного за мамины деньги.

    [Ответить]


  3. Василий :

    Что-то я не понял, зачем вам тут (f)lock понадобился. Приложение однопоточное, в каждый момент времени у вас может выполняться только один колбэк. Вопрос: зачем блокировка (еще и двойная)?

    [Ответить]

    Kaimi:

    ctrl+c - ctrl+v

    [Ответить]


  4. zloid :

    Добыча трафика с маркета, это что такое? Переманивание посетителей с маркета на какой-то свой сайт? Или раскрутка своего приложения на маркете?

    [Ответить]

    Kaimi:

    1ое

    [Ответить]


  5. БыдлоКодер :

    Kaimi, ты так ненавидишь быдло/говно кодеров, но почему ты сам сам активно занимаешься быдло/говно кодингом за деньги? Или это чисто прагматическая ненависть к конкурентам?

    [Ответить]

    zloid:

    Уходи, а то я тебя по айпи вычислю.

    [Ответить]

    БыдлоКодер:

    Пощади, о ужасный Ктулху.

    [Ответить]

  6. [...] и списка идентификаторов приложений (пригодится парсер из предыдущей статьи) в сжатые сроки оставит множество комментариев. [...]


  7. Kairos :

    А в C# теперь есть async/await, благодаря чему IO completion ports использовать так же удобно, как и потоки.

    [Ответить]


  8. user :

    Подскажите как можно использовать AnyEvent::Socket? На CPAN этот модуль есть, а Perl Packet Manager его не отображает для установки.

    [Ответить]


Оставьте ваш комментарий