Jetpack Compose 中的“@Stable”注释应用于函数/方法时会起什么作用?

Kam*_*Bąk 5 performance kotlin android-jetpack-compose

我看到它被用于所有Density方法,这让我很好奇。

注释文档指出了这一点When applied to a function or a property, the Stable annotation indicates that the function will return the same result if the same parameters are passed in.,但这实际上会影响性能吗?

remember我尝试用下面的代码片段测试它(认为它会跳过/缓存函数的结果,就像在内部调用它一样)

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            var counter by remember {
                mutableStateOf(0)
            }
            val key = foo(counter > 0)
            LaunchedEffect(key){
                while (isActive){
                    delay(1000)
                    counter++
                }
            }
        }
    }
}

@Stable
fun foo(toReturn: Boolean): Boolean{
    Log.d("TEST", toReturn.toString())
    return toReturn
}
Run Code Online (Sandbox Code Playgroud)

但它每秒都在记录,所以这个注释没有影响任何东西?

chu*_*ckj 7

函数上的注释@Stable意味着它是一个纯函数,并且编译器插件根据其参数对函数的结果进行假设。

这主要在编译器中用于推断值是否是静态的或相等的。例如,Double.dp扩展函数标记为@Stable。这意味着编译器可以推断,由于42是文字,因此它的值永远不会改变。因此,既然.dp是稳定的,就可以推断表达式42.dp也永远不会改变。

编译器将放弃大多数运算符表达式,因为这对于简单表达式来说只是非常安全的。

@Stable绝不意味着跳过或记忆函数的结果,因为它不会修改函数的功能,相反,它是编译器可以假设函数已经执行的操作的声明(也是函数作者的承诺,它永远稳定)。仅@Composable意味着重写函数以引入跳过。

如果你想避免调用foo(假设 foo 很昂贵),你应该使用rememberas val key = remember(counter > 0) { foo(counter > 0) },其中将使用位置记忆仅foo在表达式的值counter > 0发生变化时调用。