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 projectsArkadii 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.1msOmar 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.355msOmar 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.39sOmar 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=786msArkadii 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