2017-06-03 82 views
1

當我運行以下程序時,需要大約7到8分鐘才能執行。我真的不確定我錯在哪裏,因爲這個程序花了很多時間來執行。CopyOnWriteArraySet太慢

public class Test { 
      public static void main(String[] args) { 
      final Integer[] a= new Integer[1000000]; 
      for (int i=0; i < a.length; i++) { 
       a[i] = i; 
      } 
      final List<Integer> source = Arrays.asList(a); 
      final Set<Integer> set = new CopyOnWriteArraySet<Integer>(source); 
     } 
    } 

有人能幫助我明白了,爲什麼這個程序太慢。

我的機器是核心I7與4GB RAM

+0

正如文檔所述,CopyOnWriteArraysSet由CopyOnWriteArraysList支持,並且*最適合於集合大小通常很小的應用程序*。 100萬遠不是小的。操作是O(n^2)。 –

+0

@Siguza真的不是問題。它並不需要很多時間。 –

回答

6

我已經測試和確實與提供給構造1個000 000單元的明細表,它需要良好的時間(7分鐘)。

它是開放的JDK 2013年1月9日引用問題:
JDK-8005953 - CopyOnWriteArraySet copy constructor is unusable for large collections

的問題會導致由CopyOnWriteArraySet構造函數調用的方法CopyOnWriteArrayList#addAllAbsent()

提取物的問題:

CopyOnWriteArraySet的拷貝構造函數是大型 集合太慢。它接管了10分鐘開發筆記本電腦的集合,在短短 百萬條目被複制...

隨着分辨率的狀態,你可以閱讀:不會解決
你可以理解爲最後的消息:

addAllAbsent可以製成較大的輸入速度更快,但它會影響 表現爲小大小。據記載, CopyOnWriteXXX類更適合小尺寸 尺寸的集合。

CopyOnWriteArraySet javadoc確實指定了這一點:

它是最適合於中集大小一般留 小,只讀操作遠多於可變操作應用程序,並 你需要防止干擾在遍歷期間的線程中。

+0

看着'addAllAbsent()',它看起來像是將輸入集合(可能包含重複項)轉換爲一組唯一項目。似乎沒有任何特殊的情況下從現有的設置構建。 –