我运行了一个测试来为我的程序找到最佳的并发 Set 实现,使用非同步的 HashSet
作为控制,并得到了一个有趣的结果:addAll
Collections.synchronizedSet(HashSet)
的 >、retainAll
和 contains
操作似乎比常规 HashSet< 的操作更快
。我的理解是 SynchronizedSet(HashSet)
永远不应比 HashSet
快,因为它由带同步锁的 HashSet
组成。我已经进行了多次测试,结果相似。我做错了什么吗?
相关结果:
Testing set: HashSet
Add: 17.467758 ms
Retain: 28.865039 ms
Contains: 22.18998 ms
Total: 68.522777 ms
--
Testing set: SynchronizedSet
Add: 17.54269 ms
Retain: 20.173502 ms
Contains: 19.618188 ms
Total: 57.33438 ms
相关代码:
public class SetPerformance {
static Set<Long> source1 = new HashSet<>();
static Set<Long> source2 = new HashSet<>();
static Random rand = new Random();
public static void main(String[] args) {
Set<Long> control = new HashSet<>();
Set<Long> synch = Collections.synchronizedSet(new HashSet<Long>());
//populate sets to draw values from
System.out.println("Populating source");
for(int i = 0; i < 100000; i++) {
source1.add(rand.nextLong());
source2.add(rand.nextLong());
}
//populate sets with initial values
System.out.println("Populating test sets");
control.addAll(source1);
synch.addAll(source1);
testSet(control);
testSet(synch);
}
public static void testSet(Set<Long> set) {
System.out.println("--\nTesting set: " + set.getClass().getSimpleName());
long start = System.nanoTime();
set.addAll(source1);
long add = System.nanoTime();
set.retainAll(source1);
long retain = System.nanoTime();
boolean test;
for(int i = 0; i < 100000; i++) {
test = set.contains(rand.nextLong());
}
long contains = System.nanoTime();
System.out.println("Add: " + (add - start) / 1000000.0 + " ms");
System.out.println("Retain: " + (retain - add) / 1000000.0 + " ms");
System.out.println("Contains: " + (contains - retain) / 1000000.0 + " ms");
System.out.println("Total: " + (contains - start) / 1000000.0 + " ms");
}
}
最佳答案
您没有预热 JVM。
请注意,您首先运行 HashSet
测试。
- 我稍微更改了您的程序以循环运行测试 5 次。在我的机器上,
SynchronizedSet
更快,仅第一次测试。 - 然后,我尝试颠倒两个测试的顺序,只运行一次测试。
HashSet
又赢了。
在这里阅读更多相关信息:How do I write a correct micro-benchmark in Java?
此外,查看 Google Caliper用于处理所有这些微基准测试问题的框架。
关于java - 为什么 Collections.synchronizedSet(HashSet) 对于 addAll、retainAll 和 contains 比 HashSet 更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25066983/