2016-09-27 3 views
0

Так я наткнулся на это: https://github.com/typhoeus/typhoeusУскорить грабли задачи с помощью Typhoeus

Я интересно, если это то, что мне нужно, чтобы ускорить мой грабли задача

Event.all.each do |row| 

    begin 
    url = urlhere + row.first + row.second 
    doc = Nokogiri::HTML(open(url)) 
    doc.css('.table__row--event').each do |tablerow| 
    table = tablerow.css('.table__cell__body--location').css('h4').text 
    next unless table == row.eventvenuename 
     tablerow.css('.table__cell__body--availability').each do |button| 
     buttonurl = button.css('a')[0]['href'] 
     if buttonurl.include? '/checkout/external' 
      else 
     row.update(row: buttonurl) 
     end 
     end 
    end 
    rescue Faraday::ConnectionFailed 
    puts "connection failed" 
    next 
    end 
end 

Я интересно, если это ускорит его, или потому, что я делаю .each, не так ли?

Если бы вы могли привести пример?

Сэм

+0

это может ускорить задачу, но ваш вопрос очень странный =) у вас уже есть код, поэтому попробуйте использовать 'Typhoeus' и посмотреть, как он будет выглядеть. – Aleksey

+0

Производительность - сложный вопрос ... Мне действительно невозможно сказать, насколько быстрее он будет работать с HTTP-запросами, создаваемыми параллельно. Попробуй и посмотри! –

+1

Возможно, есть некоторые другие улучшения производительности, которые вы могли бы сделать без драгоценного камня. Выполнение 'next if table == row.eventvenuename' кажется странным. Почему бы просто не пропустить эти итерации более интеллектуальным селектором, чем 'doc.css ('. Table__row - event')'? LIkewise, для 'buttonurl.include? '/ checkout/external'' - просто настройте свой селектор. –

ответ

0

Если вы настроили Typhoeus :: Hydra для запуска параллельных запросов, вы можете быть в состоянии ускорить ваш код, если предположить, что Kernel#open звонков, что замедляет вас. Перед оптимизацией вы можете захотеть запустить тесты для проверки этого предположения.

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

class YourBatchProcessingClass 

    def initialize(batch_size: 200) 
    @batch_size = batch_size 
    @hydra = Typhoeus::Hydra.new(max_concurrency: @batch_size) 
    end 

    def perform 
    # Get an array of records 
    Event.find_in_batches(batch_size: @batch_size) do |batch| 
     # Store all the requests so we can access their responses later. 
     requests = batch.map do |record| 
     request = Typhoeus::Request.new(your_url_build_logic(record)) 
     @hydra.queue request 
     request 
     end 

     @hydra.run # Run requests in parallel 

     # Process responses from each request 
     requests.each do |request| 
     your_response_processing(request.response.body) 
     end 
    end 
    rescue WhateverError => e 
    puts e.message 
    end 

    private 

    def your_url_build_logic(event) 
    # TODO 
    end 

    def your_response_processing(response_body) 
    # TODO 
    end 

end 

# Run the service by calling this in your Rake task definition 
YourBatchProcessingClass.new.perform 

Рубин может быть использованы для чистых сценариев, но она работает лучше всего, как объектно-ориентированный язык. Разделение вашей обработки на четкие методы может помочь прояснить ваш код и помочь вам поймать такие вещи, как Том Лорд, упомянутый в комментариях к вашему вопросу. Кроме того, вместо того, чтобы обернуть весь ваш скрипт в блоке begin..rescue, вы можете использовать уровень метода rescue s, как в #perform выше, или просто обернуть @hydra.run.

Как примечание, .all.each является борами памяти, и, таким образом, считается плохим решением итерации записи: .all загружает все записи в память, прежде чем итерация над ними .each. Чтобы сохранить память, лучше использовать .find_each или .find_in_batches, в зависимости от вашего варианта использования. Смотрите: http://api.rubyonrails.org/classes/ActiveRecord/Batches.html

Смежные вопросы