gpt4 book ai didi

java - Guava Multimaps.filterKeys 与 NavigableMap.subMap() 相比性能较差

转载 作者:行者123 更新时间:2023-11-30 05:52:17 26 4
gpt4 key购买 nike

我有一个 Guava TreeMultimap ,它将 Date 键映射到某个值。

我希望能够过滤此 map 以查找 key 在特定日期范围内的位置。

由于 map 已排序,应该可以非常快速地完成此操作,而无需评估所有键,但是当我第一次使用 Multimaps.filterKeys 编写此操作时,它比预期慢得多,表明它正在评估每个键。当我使用 NavigableMap.subMap() 重写此代码时,性能非常好,达到了我的预期。

Multimaps.filterKeys 语法更好,这也是我想要使用的,特别是因为我已经在使用 Multimap

请参阅下面我正在做的最小化示例:

import java.text.MessageFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Range;
import com.google.common.collect.TreeMultimap;

public class MapPerformanceTest
{
public static void main(final String[] args)
{
System.out.println("Populating Map...");

final TreeMultimap<Date, Integer> map = TreeMultimap.create();

for (int i = 0; i < 20000000; i++)
{
map.put(new Date(i), i);
}

final Date[] range = {new Date(10), new Date(20)};

System.out.println("Map Populated");
System.out.println();

long tempTime = -System.nanoTime();

System.out.println(MessageFormat.format("Multimaps.filterKeys() attempt #1 returned {0} keys in {1} milliseconds",
Multimaps.filterKeys(map, Range.closed(range[0], range[1])).size(),
TimeUnit.MILLISECONDS.convert(tempTime + System.nanoTime(), TimeUnit.NANOSECONDS)));

tempTime = -System.nanoTime();

System.out.println(MessageFormat.format("NavigableMap.subMap() attempt #1 returned {0} keys in {1} milliseconds",
map.asMap().subMap(range[0], true, range[1], true).size(), TimeUnit.MILLISECONDS.convert(tempTime + System.nanoTime(), TimeUnit.NANOSECONDS)));

tempTime = -System.nanoTime();

System.out.println(MessageFormat.format("NavigableMap.subMap() attempt #2 returned {0} keys in {1} milliseconds",
map.asMap().subMap(range[0], true, range[1], true).size(), TimeUnit.MILLISECONDS.convert(tempTime + System.nanoTime(), TimeUnit.NANOSECONDS)));

tempTime = -System.nanoTime();

System.out.println(MessageFormat.format("Multimaps.filterKeys() attempt #2 returned {0} keys in {1} milliseconds",
Multimaps.filterKeys(map, Range.closed(range[0], range[1])).size(),
TimeUnit.MILLISECONDS.convert(tempTime + System.nanoTime(), TimeUnit.NANOSECONDS)));
}
}

输出为:

Multimaps.filterKeys() attempt #1 returned 11 keys in 1,418 milliseconds
NavigableMap.subMap() attempt #1 returned 11 keys in 1 milliseconds
NavigableMap.subMap() attempt #2 returned 11 keys in 0 milliseconds
Multimaps.filterKeys() attempt #2 returned 11 keys in 946 milliseconds

最佳答案

您认为过滤比迭代子图慢的观察是正确的。解释是过滤确实涉及评估每个键,正如您所怀疑的那样。

这是过滤方法所固有的。 filterKeys 方法无法查看提供的过滤器内部以确定其功能。因此有必要将过滤器应用于所有键。

现在,如果编译器深入了解方法和过滤器正在做什么,理论上它就有可能将过滤转换为更有效的东西。不幸的是,事实并非如此,因此如果您希望在具有许多键的 map 上操作时获得良好的性能,则有必要使用更麻烦的子 map 方法。

关于java - Guava Multimaps.filterKeys 与 NavigableMap.subMap() 相比性能较差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53682912/

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