2014-10-04 50 views
0

我正在處理文本文檔解析應用程序。無法找出正確的數據結構和正確的方法在這種情況下解析文本

  1. 文件包含 頁的ArrayList:

    文檔的設計圖中的figure

    下面是如何解析正在做的是,如圖所示。

  2. 每個頁面都有一個Map<float, List<Character>>

float值包含一個字符位置的y軸值,因此一個key和字符包含其它信息。

解析是通過第三方庫逐字符完成的。如果需要更多信息,請添加評論。

現在,在解析時,我創建了兩個ExecutorService線程池,一個用於頁面,另一個用於填充地圖。

我最初創建一個文檔並將每個頁面傳遞給page parser作爲可運行到ExecutorService。它依次將empty map傳遞給文本解析器。

文本解析器檢查map是否有鍵值 如果是,它會將字符添加到列表或新列表中,這是必要的。

這裏的問題是,這個任務可以同時完成所有頁面以加速執行。但是我無法處理這個數據結構,因爲所有的線程如果正常解析,並且如果使用Collections.synchronizedMap以同步方式完成,則需要花費大量時間。

此外,我維護Future對象的兩個不同列表來檢查線程是否完成。

請提供寶貴的改進建議和併發執行以加快執行速度。

+1

開始以最簡單的方式在單個線程中執行此操作,並查看它是否足夠快。如果不是,測量什麼需要時間,並嘗試優化。同時做大量的事情並不是加速做事的神奇方式。它具有由於上下文切換,同步,增加的複雜性等原因而產生的固有成本。 – 2014-10-04 19:53:43

+0

Nizet我同意但是當你解析一個大約5k頁面的文檔時,我必須等待一分鐘。單線程肯定不是這個解決方案。一旦地圖準備就緒後,還會進行進一步的計算 – 2014-10-04 19:58:28

+1

然後嘗試採用簡單的分工策略。您有5000頁,4個CPU內核。因此,創建4個線程,每個線程解析1250個頁面,並在完成後彙總結果。 – 2014-10-04 20:02:21

回答

2

如果每個頁面都有自己的Map<float, List<Character>>,那麼永遠不會有多個線程處理單個頁面 - 那麼您將不需要同步對Map的訪問或使用併發Map實現。正如JB Nizet在評論中所建議的那樣,您可以靜態分配工作人員中的網頁;另一種選擇是將所有頁面放在ConcurrentLinkedQueue中,並讓工作人員poll爲解析頁面的隊列,當隊列爲空時(poll返回null)終止。無論哪種方式,您只需要一個ExecutorService,因爲每個工作人員都負責解析和地圖填充。

相關問題