Omar Mainegra
05/29/2020, 4:14 PMconcatMap
.
This is what I found
@Test
fun Operator_durations() {
val concatMapDuration = measureTime {
(1..100).asObservable().concatMap { (1..100).asObservable() }.test().values
}
val flatMapDuration = measureTime {
(1..100).asObservable().flatMap { (1..100).asObservable() }.test().values
}
println("Measured: concatMap=$concatMapDuration, flatMap=$flatMapDuration")
}
Output
[iOS] Measured: concatMap=7.68s, flatMap=7.47s
[JVM] Measured: concatMap=122ms, flatMap=36.6ms
[JS ] Measured: concatMap=241ms, flatMap=147ms
As you can see iOS time is a magnitude higherArkadii Ivanov
05/29/2020, 6:05 PMArkadii Ivanov
05/29/2020, 6:05 PMOmar Mainegra
05/29/2020, 6:06 PMArkadii Ivanov
05/29/2020, 6:07 PMArkadii Ivanov
05/29/2020, 6:07 PMOmar Mainegra
05/29/2020, 6:08 PMOmar Mainegra
05/29/2020, 6:42 PMOmar Mainegra
05/29/2020, 6:43 PM./gradlew tasks|grep link
linkDebugFrameworkIos - Links a framework 'debugFramework' for a target 'ios'.
linkDebugFrameworkIosArm64 - Links a framework 'debugFramework' for a target 'iosArm64'.
linkDebugTestIos - Links a test executable 'debugTest' for a target 'ios'.
linkDebugTestIosArm64 - Links a test executable 'debugTest' for a target 'iosArm64'.
linkReleaseFrameworkIos - Links a framework 'releaseFramework' for a target 'ios'.
linkReleaseFrameworkIosArm64 - Links a framework 'releaseFramework' for a target 'iosArm64'.
kotlinNpmInstall - Find, download and link NPM dependencies and projects
Arkadii Ivanov
05/29/2020, 10:25 PMArkadii Ivanov
05/30/2020, 11:45 AMOmar Mainegra
06/01/2020, 2:27 PMMeasured: concatMap=14.1ms, flatMap=12.9ms
Debug:
Measured: concatMap=39.8ms, flatMap=35.1ms
Omar Mainegra
06/01/2020, 2:29 PMX64
, is not like is virtualized or anything. I really don't see any reason for such a bad performanceArkadii Ivanov
06/01/2020, 3:13 PMArkadii Ivanov
06/01/2020, 3:16 PMArkadii Ivanov
06/01/2020, 3:17 PMOmar Mainegra
06/01/2020, 3:17 PMOmar Mainegra
06/01/2020, 3:18 PMtestReleaseUnitTest
and this is the result (without using TestObserver)Omar Mainegra
06/01/2020, 3:18 PMMeasured: concatMap=11.595ms, flatMap=4.355ms
Omar Mainegra
06/01/2020, 3:19 PMOmar Mainegra
06/01/2020, 7:22 PMTestObservableObserver
(since it wasn't a test) but a plain subscribe
. This is the new measureOmar Mainegra
06/01/2020, 7:22 PM@Test
fun Operator_durations() {
val N = 100
var sum1 = 0
var sum2 = 0
var sum3 = 0
val expectedSum = N*(N + 1)/2*N
val duration1 = measureTime {
sum1 = (1..100).asObservable().concatMap { (1..100).asObservable() }.test().values.sum()
}
val duration2 = measureTime {
(1..100).asObservable().concatMap { (1..100).asObservable() }.subscribe { sum2 += it }
}
val duration3 = measureTime {
val list = AtomicReference<List<Int>>(emptyList())
(1..100).asObservable().concatMap { (1..100).asObservable() }.subscribe { list.value = list.value + it }
sum3 = list.value.sum()
}
assertEquals(expectedSum, sum1)
assertEquals(expectedSum, sum2)
assertEquals(expectedSum, sum3)
println("Measured: duration1=$duration1, duration2=$duration2, duration3=$duration3")
}
Omar Mainegra
06/01/2020, 7:23 PMMeasured: duration1=10.9s, duration2=43.2ms, duration3=7.39s
Omar Mainegra
06/01/2020, 7:48 PMAtomicReference<List<Int>>
// DEBUG
Measured: duration1=49.5ms, duration2=6.69s
Measured: duration1=69.5ms, duration2=6.57s
Measured: duration1=63.9ms, duration2=6.70s
// RELEASE
Measured: duration1=26.9ms, duration2=814ms
Measured: duration1=25.3ms, duration2=795ms
Measured: duration1=26.7ms, duration2=786ms
Arkadii Ivanov
06/01/2020, 11:01 PMArkadii Ivanov
06/01/2020, 11:21 PMTestObservableObserver
so it will use mutable list by default and fallback to immutable if frozen. This will dramatically improve performance in such cases. You will also need to call it like .test(autoFreeze = false)
. What do you think?Omar Mainegra
06/01/2020, 11:45 PMArkadii Ivanov
06/02/2020, 4:54 AMonNext
callback is already synchronized by definition. So just initialize the AtomicReferenec with an empty mutable list and every time check whether it is frozen or not. If not then just add the item, otherwise fallback to the current approach.Arkadii Ivanov
06/04/2020, 10:11 PMOmar Mainegra
06/05/2020, 1:09 AM