KT-55091 Optimize Sequence::toSet/toList implementation

Sequence::toSet and Sequence::toList both create a
collection, fill it with elements, and then try to optimize a result
by returning empty, singleton, or the allocated collection depending on
the elements count.
Instead of allocating the collection and then trying to return
an optimized instance it is worth checking the sequence's size
beforehand and return empty/singleton collection when possible.

Proposed change optimize performance of aforementioned functions and
also reduce allocation rate when a sequence consists of 0 or 1 elements.

^KT-55091 fixed
This commit is contained in:
Filipp Zhinkin
2023-04-11 11:51:01 +02:00
committed by Space Team
parent e8be3043cc
commit 368f21461c
3 changed files with 52 additions and 6 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@@ -745,6 +745,20 @@ public class SequenceTest {
assertNull(fibonacci().take(10).firstNotNullOfOrNull { it.doubleIfNotMonodigit() })
}
@Test fun toSet() {
assertEquals(emptySet(), emptySequence<Int>().toSet())
assertEquals(setOf(42), sequenceOf(42).toSet())
assertEquals(setOf(3, 2, 1), sequenceOf(3, 2, 1).toSet())
assertEquals(setOf(1, 2, 3), sequenceOf(1, 2, 1, 3, 2, 3).toSet())
}
@Test fun toList() {
assertEquals(emptyList(), emptySequence<Int>().toList())
assertEquals(listOf(42), sequenceOf(42).toList())
assertEquals(listOf(3, 2, 1), sequenceOf(3, 2, 1).toList())
assertEquals(listOf(1, 2, 1, 3, 2, 3), sequenceOf(1, 2, 1, 3, 2, 3).toList())
}
/*
test fun pairIterator() {
val pairStr = (fibonacci() zip fibonacci().map { i -> i*2 }).joinToString(limit = 10)