android - 挂起功能的执行时间差异巨大
问题描述
我仍然试图围绕挂起函数以及 IO 绑定和 CPU 绑定挂起函数之间的区别(如果有的话)以及其他事情。
我在主线程中启动一个协程,并以不同的方式运行一个 CPU 密集型函数,看看会发生什么。
class TestActivity : AppCompatActivity(), CoroutineScope {
private val job = Job()
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
launch {
val start = System.currentTimeMillis()
Log.d("test", "start: $start")
fib(24)
val finish = System.currentTimeMillis()
Log.d("test", "finish: $finish")
Log.d("test", "duration: ${finish - start}")
}
}
我已经尝试了该功能的这三种变体fib
:
private fun fib(x: Int): Int =
if (x <= 1) x else fib(x - 1) + fib(x - 2)
常规方式:xml 不会立即膨胀,并且该函数需要 0.1 秒才能运行。
private suspend fun fib(x: Int): Int =
if (x <= 1) x else fib(x - 1) + fib(x - 2)
常规方式 +suspend
关键字:xml 不会立即膨胀,并且该函数需要 1.3 秒才能运行。
private suspend fun fib(x: Int): Int =
withContext(Dispatchers.Default) { if (x <= 1) x else fib(x - 1) + fib(x - 2) }
常规方式 +suspend
关键字 + 用 包装它withContext(Dispatchers.Default)
:xml 立即膨胀,并且该函数需要 25 秒才能运行。
任何人都可以解释为什么这三个功能之间的持续时间有如此大的差异吗?
解决方案
private fun fib(x: Int): Int =
if (x <= 1) x else fib(x - 1) + fib(x - 2)
这是你的基本情况,斐波那契的一个极其低效的递归实现。它的计算fib(x - 1)
完全独立于fib(x - 2)
,这导致函数调用呈指数级增长。计算fib(24)
它大约(黄金比例)24 = 103,682 次调用。
private suspend fun fib(x: Int): Int =
if (x <= 1) x else fib(x - 1) + fib(x - 2)
从语义上讲,这与上面完全相同。声明为可挂起的函数,但挂起点为零。由于可挂起函数固有的 CPS 转换开销,它更慢。
private suspend fun fib(x: Int): Int =
withContext(Dispatchers.Default) { if (x <= 1) x else fib(x - 1) + fib(x - 2) }
在这里,您实际上实现了一些并行性,但并行加速与分派非常小的工作的开销相比相形见绌。此外,由于要计算斐波那契数列的第 n 个成员,您需要已经计算的 (n - 1) 和 (n - 2)并行化斐波那契。在您的情况下,您对相同的成员进行了很多重新计算,因此可以通过并行性来改进,但仍然远远不能正确实现单线程解决方案。
推荐阅读
- webots - 测量车辆尺寸
- sql - 如何选择非付费用户?
- c - 为什么在我的程序中将 0a 字节和 20 转换为空字节?
- powershell - 新建项目创建无扩展名文件而不是目录
- html - Float:right 受其父 div 的限制,使其右对齐/下一行
- c# - 为什么我的代码在相机视图中的一个游戏对象被销毁时一次生成两个游戏对象(而不是一个)?
- ios - 在 Xcode 11,beta 2 的 Interface Builder 中指定条形颜色时,iOS 13 的 UITabBarItem 图标颜色不正确
- sas - 使用正则表达式删除宏变量括号内的文本
- python - 在随机矩阵中找到最可能的区域
- forms - 在 TYPO3 扩展中创建表单并处理结果