Android-协程比RX慢,在long for循环中计算时

问题描述 投票:0回答:1

[尝试一个简单的应用程序,其中一个使用协程添加variable i,另一个使用Completable中的RxJava

公司代码:

val timeCoroutineStart = System.currentTimeMillis()
    CoroutineScope(Dispatchers.IO).launch {
        var i = 0
        repeat(1000000000) {
            i++
        }
        Log.d(
            "TASK_TIME",
            "COROUTINE: ${System.currentTimeMillis() - timeCoroutineStart}"
        )
    }.start()

Rx代码:

val timeRxStart = System.currentTimeMillis()
Completable.create{
        var i = 0
        repeat(1000000000) {
            i++
        }
        it.onComplete()
    }.subscribeOn(Schedulers.io()).subscribe {
        Log.d(
            "TASK_TIME",
            "RX: ${System.currentTimeMillis() - timeRxStart}"
        )
    }

结果:

D/TASK_TIME: RX: 1720
D/TASK_TIME: COROUTINE: 20873

我使用协程还很陌生,想尝试一些非常简单的方法。值得注意的是,较小的for循环协程为MUCH faster。我使用错了吗?还是协程比RX更长的计算时间有缺点?

编辑

在JVM(不是Android)上运行Coroutine代码与Rx非常相似,因此,在Android上运行的完全相同的代码具有与在JVM上运行不同的性能

android rx-java kotlin-coroutines
1个回答
0
投票
var i = 0
repeat(1000000000) {
    i++
}

这是一种非常幼稚的微标记方法。 JIT编译器将整个循环变为无操作,而只是将最终结果直接分配给i。基本上,您还没有建立任何相关且稳定的结果。

此外,由于您并不是真正测试框架的功能,而是以琐碎的方式使用它们,而整个逻辑都在一个代码块中,所以即使更改循环也无济于事。

您应该对基准进行更接近于预期用例的基准测试,并且应该将测量本身放在外部循环中,重复相同的测量几秒钟并取平均值。最好还应该从统计信息中减去大约第一秒,以避免预热效应。


-1
投票

这不是你的方式launch a coroutine

根据您的情况,上述方法的主体在main thread中执行。这就是为什么it's slow!您需要launch a suspend method包含heavy work!尝试:-

val timeCoroutineStart = System.currentTimeMillis()
CoroutineScope(Dispatchers.IO).launch {
    comparison()
}

suspend fun comparison() {
     withContext(Dispatchers.DEFAULT) {
        var i = 0
        repeat(1000000000) {
           i++
        }
        Log.d(
          "TASK_TIME",
          "COROUTINE: ${System.currentTimeMillis() - timeCoroutineStart}"
        )
     }
}

-2
投票

您可以从Comparision获得有关RXJava和协程的性能的更多详细信息:>

在RXJava和协程的比较中,最重要的因素是内存和CPU消耗。

© www.soinside.com 2019 - 2024. All rights reserved.