嗨我有1330个对象的列表,并希望应用方法并获得设置作为结果。
val result = listOf1330
.asSequence()
.map {
someMethod(it)
}
val resultSet = result.toSet()
它没有toSet工作正常,但如果那时执行时间大约是10倍。我已经使用序列来使它更快地工作,但结果是我需要列表而没有重复(set)。
简单地说:将序列转换为set的最有效方法是什么?
val result = listOf1330.mapTo(HashSet()) { someMethod(it) }
使用流或序列来实现转换没有多大意义 - 您将需要集合中的所有元素,而不是几个元素。 mapTo
(和map
)函数是Kotlin中的inline
。这意味着代码将被替换为调用站点,它不会创建和执行lambda多次。我们使用mapTo
来避免toSet()
函数完成的第二个集合。
如果你想在几个线程中运行计算,.parallelStream()
可能会增加更多的性能。测量线程之间的负载平衡程度仍然是一个好主意。性能可能取决于您调用它的集合实现类
如果您的someObject
执行equals()
或hashCode()
的速度很慢,或者为许多对象提供相同的哈希码,那么这可能会导致延迟,并且您可以对其进行改进。
否则,如果对象很大,延迟可能主要是由于必须访问以存储它们的所有内存量。如果是这样的话,如果你想要一个包含内存中所有这些对象的集合,这就是你必须付出的代价。
Sequence.toSet()
使用LinkedHashSet
。您可以尝试使用例如另一个Set
实例。 toCollection(HashSet())
,看看是否更快。 (但是你不会得到相同的迭代顺序。)
我同意gidds
对HashSet
和LinkedHashSet
表现的回答。
LinkedHashSet的插入比HashSet更昂贵;
但是,在上面的用例中,我认为我们可以利用parallelStream
来提高性能。在引擎盖下,Kotlin使用Java parallelStream。
val result: Set<String> = listOf("sdgds", "fdgdfsg", "dsfgsdfg")
.parallelStream()
.map {
someMethod(it)
}.collect(Collectors.toSet())
Collectors.toSet()
使用HashSet
。所以,我们应该在插入性能方面做得好。