2009-08-20 24 views
0

我正在製作一個數據密集型Web應用程序,我正試圖優化。我聽說過分叉和線程化,但我不知道它們是否適用於我正在嘗試做的事情,以及如何實現它們。我的代碼如下所示:如何加快我的Ruby應用程序?

def search 
     @amazon_data=Hash.from_xml(item.retrieve_amazon(params[:sku])) 
     unless @amazon_data['results'] == nil 
      @amazon_data['results']['item'].size.times do |i| 
      @all_books << { :vendor => 'Amazon.com', 
          :price => @amazon_data['results']['item'][i]['price'].to_f, 
          :shipping => @amazon_data['results']['item'][i]['ship'].to_f, 
          :condition => @amazon_data['results']['item'][i]['condition'], 
          :total => @amazon_data['results']['item'][i]['price'].to_f + @amazon_data['results']['item'][i]['ship'].to_f, 
          :availability => 'In Stock', 
          :link_text => 'Go to Amazon.com', 
          :link_url => "http://www.amazon.com/gp/offer-listing/#{params[:isbn]}" 
      } 
     end 
     end 
     @ebay_data=Hash.from_xml(Book.retrieve_ebay(params[:sku])) 
     unless @ebay_data['results'] == nil 
      @ebay_data['results']['item'].size.times do |i| 
      @all_books << { :vendor => 'eBay', 
          :price => @ebay_data['results']['item'][i]['price'].to_f, 
          :shipping => @ebay_data['results']['item'][i]['ship'].to_f, 
          :condition => 'Used', 
          :total => @ebay_data['results']['item'][i]['price'].to_f + @ebay_data['results']['item'][i]['ship'].to_f, 
          :availability => 'In Stock', 
          :link_text => 'Go to eBay', 
          :link_url => "http://www.amazon.com/gp/offer-listing/#{params[:sku]}" 
      } 
     end 
    end 
    end 

所以,基本上我有什麼是檢索來自eBay和亞馬遜的數據,並在此解析它兩個動作。我該如何讓這兩個動作同時運行?叉子或線程與我想要完成的事情有什麼關係?


這會將API時間縮短一半,但我不知道如何返回結果。在返回API結果之前加載後續視圖....但是,它正在返回數據。當我在代碼

puts @all_books 

內線程結果顯示在控制檯。但是,線程之外,結果不會返回。

def search 
    Thread.new do 
     @amazon_data=Hash.from_xml(item.retrieve_amazon(params[:sku])) 
     unless @amazon_data['results'] == nil 
      @amazon_data['results']['item'].size.times do |i| 
      @all_books << { :vendor => 'Amazon.com', 
          :price => @amazon_data['results']['item'][i]['price'].to_f, 
          :shipping => @amazon_data['results']['item'][i]['ship'].to_f, 
          :condition => @amazon_data['results']['item'][i]['condition'], 
          :total => @amazon_data['results']['item'][i]['price'].to_f + @amazon_data['results']['item'][i]['ship'].to_f, 
          :availability => 'In Stock', 
          :link_text => 'Go to Amazon.com', 
          :link_url => "http://www.amazon.com/gp/offer-listing/#{params[:isbn]}" 
      } 
     end 
     end 
    end 
    Thread.new do 
     @ebay_data=Hash.from_xml(Book.retrieve_ebay(params[:sku])) 
     unless @ebay_data['results'] == nil 
      @ebay_data['results']['item'].size.times do |i| 
      @all_books << { :vendor => 'eBay', 
          :price => @ebay_data['results']['item'][i]['price'].to_f, 
          :shipping => @ebay_data['results']['item'][i]['ship'].to_f, 
          :condition => 'Used', 
          :total => @ebay_data['results']['item'][i]['price'].to_f + @ebay_data['results']['item'][i]['ship'].to_f, 
          :availability => 'In Stock', 
          :link_text => 'Go to eBay', 
          :link_url => "http://www.amazon.com/gp/offer-listing/#{params[:sku]}" 
      } 
     end 
     end 
    end 
    end 

我在正確的軌道上嗎?我怎樣才能從線程內返回結果?它是隻能在線程中訪問的變量,還是問題在於程序在返回結果之前進行的事實?


不幸的是,應用程序需要實時用戶輸入來查詢API。返回的數據必須是新鮮的,因爲它與市場中的產品定價有關......例如,用戶將進入SKU,並且通過該信息該程序將向適用的網站(亞馬遜和eBay在這種情況下。)目前,它向亞馬遜提出請求,解析數據,格式化數據,然後轉向eBay,分析數據並格式化數據。然後格式化的數據顯示在視圖中。

我的想法是,如果我可以同時進行這些API調用(在不同的線程上),它可以節省Web服務端的時間,因爲所有需要的是解析返回的數據並正確格式化。 (我可能也可以加快......)

回答

1

是的,我仍然認爲在這種情況下,您最好帶一份工作調度程序。像這樣的一個動作可以執行的絕對最快的是兩個API請求的較慢的 ---並且您對網絡延遲,對遠程API的負載等沒有保證。另一方面,您將不得不實施一些Javascript代碼可以定期輪詢以檢測作業完成情況並通知用戶結果。

此外,在ruby 1.8中的線程行爲有時會有些時髦,特別是在規模上,所以要小心。

0

很難說沒有更多信息,但我懷疑是等待API響應是大部分時間花費在哪裏。

嘗試一種不同的方法,其中API響應的請求和處理是在與Web服務進程不同的進程中處理的。前端代碼可能必須定期輪詢結果,並將操作結果注入頁面。但勝利是整個請求沒有得到支持,等待亞馬遜和Ebay做他們的勝利。

有幾個插件可以幫助,delayed_job是一個很好的開始。

0

您也可以看看EventMachine,它允許您以非阻塞方式執行出站網絡呼叫。如果您可以將第一個結果返回給用戶,那麼通過ajax獲得最終結果,用戶交互感覺會更快。

這與Kayak.com的實時航班搜索功能類似。

您也可以考慮緩存結果,將這些結果快速返回給用戶,然後通過ajax填充更新後的結果(即加載的異步)。 (你必須找出正確的用戶界面,也許只是把「流行」的結果放在折線之上,然後在折線下面或最近的更新)

* EventMachine很複雜

相關問題