2016-02-27 29 views
0

我使用Kuchiki解析某些HTML並使用hyper發出HTTP請求,以便通過scoped_threadpool對結果進行併發操作。捕獲無法複製的移動值

我選擇和遍歷目錄。我決定線程的數量基於上市數量的線程池來分配:

let listings = document.select("table.listings").unwrap(); 
let mut pool = Pool::new(listings.count() as u32); 
pool.scoped(|scope| { 
    for listing in listings { 
     do_stuff_with(listing); 
    } 
}); 

當我嘗試這樣做,我得到capture of moved value: listingslistingskuchiki::iter::Select<kuchiki::iter::Elements<kuchiki::iter::Descendants>>,它是不可複製的 - 所以我既沒有隱式克隆也沒有明確的.clone

泳池內我可以再次做document.select("table.listings"),它會工作,但這對我來說似乎沒有必要,因爲我已經使用它來計數。循環後我不需要listings

有什麼辦法,我在一個封閉使用不可複製的價值呢?

回答

3

可悲的是,我認爲這是不可能的,你想這樣做的方式。

listings.count()消耗迭代listings。您可以通過編寫listings.by_ref().count()避免這種情況,但這不會收到預期的效果,因爲count()會消耗迭代的所有元素,這樣就next()下一次調用總是產生None

做實現自己的目標的唯一途徑就是以某種方式獲得迭代器listings的長度不消耗它的元素。特性ExactSizeIterator是爲此目的而構建的,但似乎kuchiki::iter::Select未實現它。請注意,對於那種迭代器,這可能也是不可能的。

編輯:正如@delnan建議的那樣,另一種可能性是將迭代器收集到Vec中。這有一些缺點,但在你的情況下可能是一個好主意。


也讓我注意,你可能不應該在SELECT結果集的每一行創建一個線程。通常,線程池使用的線程幾乎與CPU一樣多。

+0

我試着專門使用num_cpus,並使線程池的大小,但它是_much_較慢。我不確定如何在這種情況下確定最佳的線程池大小。當我不使用線程池並在循環中產生一個線程時,它可以正常工作(並且速度很快)。任何其他建議呢? –

+0

我沒有任何好的建議,除了:措施,措施,措施。例如:當使用'num_cpus'時,所有CPU核心是否滿載?您也可以使用兩倍的CPU數量。我不知道'scoped_threadpool'使用的算法:可能每個線程的工作量太少,以至於大部分時間都需要調度...... - >我不知道,對不起;) –

+0

是'do_stuff_with' I/O重?那麼有意義的是,N個線程不能使N個CPU飽和,並且如果你有強大的I/O連接,他們可能無法飽和。但是,如果最終可能會出現數千個'listing',它可能會降低性能來啓動多個*線程,所以我建議您嘗試一個(可能很大的)多倍的CPU數量。 – delnan