2017-06-03 89 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()',它看起来像是将输入集合(可能包含重复项)转换为一组唯一项目。似乎没有任何特殊的情况下从现有的设置构建。 –