You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android秒表优化:Kotlin协程小delay及后台计算可行性探讨

Android秒表的协程实现优化与疑问

我正在开发一款每0.1秒刷新一次的Android秒表,初始实现用Kotlin协程的delay(100)控制刷新频率,代码如下:

suspend fun stopwatch() {
    val startTime = System.currentTimeMillis()
    var lastSeconds = 0L
    while (true) {
        // 控制刷新频率
        delay(100)
        // 计算已流逝时间
        val elapsedTime = System.currentTimeMillis() - startTime
        val seconds = elapsedTime / 1000
        // 仅当数值变化时更新UI
        if (seconds != lastSeconds) {
            print("${seconds}s\r")
            lastSeconds = seconds
        }
    }
}

因为delay的开销比Thread.sleep和handler.post更低,我想提升刷新频率,比如用delay(10)甚至delay(0),让秒表尽可能频繁刷新的同时,不阻塞UI队列执行其他任务。

我写了测试代码对比无delay和带delay(0)的循环耗时,测试代码及结果如下:

suspend fun test() {
    val iterations = 10_000_000_000
    val timeWithNoDelay = measureTimeMillis {
        var count = 0L
        while(count < iterations) {
            count++
        }
    }
    val timeWithDelay = measureTimeMillis {
        var count = 0L
        while(count < iterations){
            delay(0)
            count++
        }
    }
    println("time: $timeWithNoDelay, $timeWithDelay")
    println("time per iteration: ${timeWithNoDelay.toDouble() / iterations}, ${timeWithDelay.toDouble() / iterations}")
    val timeDelay = timeWithDelay - timeWithNoDelay
    println("delay equivalent to ${timeDelay.toDouble() / timeWithNoDelay} additions")
}

测试输出:

time: 3637, 16543
time per iteration: 3.637E-7, 1.6543E-6
delay equivalent to 3.548529007423701 additions

查阅Kotlin协程文档得知,当delay参数非正时会立即返回,测试中的耗时差异来自参数判断逻辑。改用yield替代后,测试结果如下:

time: 414, 32715
iterations: 1000000000, time per iteration: 4.14E-7, 3.2715E-5
delay equivalent to 78.02173913043478 additions

另外我还有个疑问:如果每秒仅100次迭代(耗时约7ms),有没有必要把秒表的计算逻辑通过withContext(Dispatchers.Default)放到后台线程执行?相关测试代码及结果如下:

import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.yield
import kotlin.system.measureTimeMillis

fun test(iterations: Long){
    val startTime = 0
    val formattedTime = MutableStateFlow("")
    val time = measureTimeMillis {
        for (i in 0..iterations) {
            val elapsedTime = System.currentTimeMillis() - startTime
            formattedTime.value = "$elapsedTime ms"
        }
    }
    println("iterations: $iterations, time: $time, time per iteration: ${time.toDouble()/iterations}")
    runBlocking {
        val startTime = 0
        val formattedTime = MutableStateFlow("")
        val timeWithDelay = measureTimeMillis {
            for (i in 0..iterations) {
                val elapsedTime = System.currentTimeMillis() - startTime
                formattedTime.value = "$elapsedTime ms"
                yield() // 等效于delay(0)
            }
        }
        println("iterations: $iterations, timeWithDelay: $timeWithDelay, time per iteration: ${timeWithDelay.toDouble()/iterations}")
    }
}

fun main(){
    test(100)
}

测试输出:

iterations: 100, time: 6, time per iteration: 0.06
iterations: 100, timeWithDelay: 7, time per iteration: 0.07

内容的提问来源于stack exchange,提问作者BPDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 01:05:05