【发布时间】:2011-01-25 11:28:23
【问题描述】:
我有以下代码,我使用 superList 和 subList ,我想检查 subList 实际上是 superList 的子列表。
我的对象没有实现 hashCode 或 equals 方法。我在测试中创造了类似的情况。当我运行测试时,结果显示 JDK 集合和普通集合的结果之间存在很大的性能差异。运行测试后,我得到以下输出。
Java Collection API 8953 MilliSeconds 的时间已过,结果为真 使用 Commons Collection API 78 MilliSeconds 的时间流逝&结果为真
我的问题是为什么 java collection 处理 containsAll 操作这么慢。我在那里做错了吗?我无法控制从遗留代码中获取的集合类型。我知道如果我将 HashSet 用于 superList,那么使用 JDK containsAll 操作会获得很大的性能提升,但不幸的是,这对我来说是不可能的。
package com.mycompany.tests;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import org.apache.commons.collections.CollectionUtils;
import org.junit.Before;
import org.junit.Test;
public class CollectionComparison_UnitTest {
private Collection<MyClass> superList = new ArrayList<MyClass>();
private Collection<MyClass> subList = new HashSet<MyClass>(50000);
@Before
public void setUp() throws Exception {
for (int i = 0; i < 50000; i++) {
MyClass myClass = new MyClass(i + "A String");
superList.add(myClass);
subList.add(myClass);
}
@Test
public void testIt() {
long startTime = System.currentTimeMillis();
boolean isSubList = superList.containsAll(subList);
System.out.println("Time Lapsed with Java Collection API "
+ (System.currentTimeMillis() - startTime)
+ " MilliSeconds & Result is " + isSubList);
startTime = System.currentTimeMillis();
isSubList = CollectionUtils.isSubCollection(subList, superList);
System.out.println("Time Lapsed with Commons Collection API "
+ (System.currentTimeMillis() - startTime)
+ " MilliSeconds & Result is " + isSubList);
}
}
class MyClass {
String myString;
MyClass(String myString) {
this.myString = myString;
}
String getMyString() {
return myString;
}
}
【问题讨论】:
-
我的猜测是,commons 集合会获取数据的副本,而不是原始数据的视图。这可能会对性能产生很大影响。
-
这个测试不够好,无法得出结论。您应该围绕测试进行迭代,以确保它有足够长的时间来衡量性能,而不是说,HotSpot 优化您的代码需要多长时间。您还应该考虑一次在一个数据结构上运行测试,即单个程序调用应该只使用其中一个数据结构。这应该有助于减轻影响结果的 JIT 编译。
标签: java list collections hashset