【发布时间】:2018-06-14 19:58:13
【问题描述】:
我编写了 3 个简单的程序来测试协程相对于线程的性能优势。每个程序都会进行很多常见的简单计算。所有程序都彼此分开运行。除了执行时间,我还通过Visual VM IDE 插件测量了 CPU 使用率。
-
第一个程序使用
1000-threaded池进行所有计算。由于频繁的上下文变化,这段代码显示了与其他代码相比最差的结果 (64326 ms):val executor = Executors.newFixedThreadPool(1000) time = generateSequence { measureTimeMillis { val comps = mutableListOf<Future<Int>>() for (i in 1..1_000_000) { comps += executor.submit<Int> { computation2(); 15 } } comps.map { it.get() }.sum() } }.take(100).sum() println("Completed in $time ms") executor.shutdownNow()
-
第二个程序具有相同的逻辑,但不是
1000-threaded池,它只使用n-threaded池(其中n等于机器的核心数量)。它显示了更好的结果 (43939 ms) 并使用更少的线程,这也很好。val executor2 = Executors.newFixedThreadPool(4) time = generateSequence { measureTimeMillis { val comps = mutableListOf<Future<Int>>() for (i in 1..1_000_000) { comps += executor2.submit<Int> { computation2(); 15 } } comps.map { it.get() }.sum() } }.take(100).sum() println("Completed in $time ms") executor2.shutdownNow()
-
第三个程序是用协程编写的,结果差异很大(从
41784 ms到81101 ms)。我很困惑,不太明白为什么它们如此不同以及为什么协程有时比线程慢(考虑到小的异步计算是协程的 forte)。代码如下:time = generateSequence { runBlocking { measureTimeMillis { val comps = mutableListOf<Deferred<Int>>() for (i in 1..1_000_000) { comps += async { computation2(); 15 } } comps.map { it.await() }.sum() } } }.take(100).sum() println("Completed in $time ms")
我实际上阅读了很多关于这些协程以及它们如何在 kotlin 中实现的信息,但在实践中,我并没有看到它们按预期工作。我做我的基准测试错了吗?或者也许我使用错了协程?
【问题讨论】:
-
您在协程示例中使用默认的协程调度程序(即
CommonPool)。尝试使用与您在其他测试中使用的相同类型的线程池。 -
请公布
computation2()的代码。结果有点取决于你在做什么,委婉地说
标签: kotlin benchmarking kotlin-coroutines