gpt4 book ai didi

java - Guava Sets.intersection 性能不佳

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:20:07 27 4
gpt4 key购买 nike

我今天在生产中遇到了一个奇怪的问题。虽然我喜欢 Guava,但我遇到了一个用例,其中 Guava 的 Sets.intersection() 表现非常糟糕。我写了一个示例代码:

Set<Long> cache = new HashSet<>();
for (long i = 0; i < 1000000; i++) {
cache.add(i);
}
Set<Long> keys = new HashSet<>();
for (long i = 0; i < 100; i++) {
keys.add(i);
}
long start = System.currentTimeMillis();
Set<Long> foundKeys = new HashSet<>();
for (Long key : keys) {
if (cache.contains(key)) {
foundKeys.add(key);
}
}
System.out.println("Java search: " + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
SetView<Long> intersection = Sets.intersection(keys, cache);
System.out.println("Guava search: " + (System.currentTimeMillis() - start));

我尝试创建一个类似的生产场景,其中我有一个 key 缓存,我正在寻找缓存中存在的所有 key 。奇怪的是,Guava 搜索比 Java 搜索花费的时间长得多。运行后我得到:

Java search: 0
Guava search: 36

谁能告诉我为什么这不适合我的用例,或者 Guava 中是否存在错误?

最佳答案

原来问题出在对 SetView.size() 的多次调用。由于 SetView 是两个集合交集的(实时) View ,因此每次都需要重新计算交集大小。

public static <E> SetView<E> intersection( final Set<E> set1, final Set<?> set2) {
//...
return new SetView<E>() {
@Override public Iterator<E> iterator() {
return Iterators.filter(set1.iterator(), inSet2);
}
@Override public int size() {
return Iterators.size(iterator());
}
//...
};
}

从这里可以看出,在这种情况下,重新计算意味着遍历整个 View ,这可能非常耗时。

解决这个问题的方法是确保 size() 只被调用一次并且值被存储(如果你知道底层集合不会改变),或者如果不可能,通过 ImmutableSet.copyOf() 创建交集的副本(例如)。

关于java - Guava Sets.intersection 性能不佳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30373758/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com