Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asynchronous Kotlin:对转换“a”有任何性能影响;“正常”;函数到阻塞挂起函数?_Asynchronous_Kotlin_Async Await_Coroutine_Kotlin Coroutines - Fatal编程技术网

Asynchronous Kotlin:对转换“a”有任何性能影响;“正常”;函数到阻塞挂起函数?

Asynchronous Kotlin:对转换“a”有任何性能影响;“正常”;函数到阻塞挂起函数?,asynchronous,kotlin,async-await,coroutine,kotlin-coroutines,Asynchronous,Kotlin,Async Await,Coroutine,Kotlin Coroutines,我有一个函数如下所示: fun <R> map(block: (T) -> R): Result<R> { ... } 所以我有两个问题: 采用“正常”函数,将其作为suspend参数传递,然后阻塞直到结果完成时,是否有任何性能方面的考虑? 根据我所读到的,它听起来像是初始线程在挂起块中继续“工作”,直到它到达第一个挂起点。然后,将延续放入等待队列,初始线程可以自由执行其他工作 然而,在本例中,没有任何“真正的”挂起点,因为实际的函数只是(t)->R,尽管我不知

我有一个函数如下所示:

fun <R> map(block: (T) -> R): Result<R> { ... }
所以我有两个问题:

  • 采用“正常”函数,将其作为
    suspend
    参数传递,然后阻塞直到结果完成时,是否有任何性能方面的考虑?
    • 根据我所读到的,它听起来像是初始线程在挂起块中继续“工作”,直到它到达第一个挂起点。然后,将延续放入等待队列,初始线程可以自由执行其他工作
    • 然而,在本例中,没有任何“真正的”挂起点,因为实际的函数只是
      (t)->R
      ,尽管我不知道编译器是否能够分辨出这一点
    • 我担心这个设置实际上是在利用池中的另一个线程,它只是通知我的第一个线程要唤醒
  • 有没有更好的方法让挂起和非挂起函数集使用相同的代码

  • 您的方法是正确的,
    runBlocking
    是专门设计用来连接阻塞和非阻塞操作的。从文件中:

    运行新的协同程序并中断当前线程,直到其 完成。此函数不应从协同程序中使用<是的 设计用于将常规阻塞代码桥接到编写的库 悬挂式,用于主要功能和测试

    还进一步改为:

    还有罗曼·艾利扎洛夫的一些有趣的视频:


    您的方法是正确的,
    runBlocking
    是专门设计用来连接阻塞和非阻塞操作的。从文件中:

    运行新的协同程序并中断当前线程,直到其 完成。此函数不应从协同程序中使用<是的 设计用于将常规阻塞代码桥接到编写的库 悬挂式,用于主要功能和测试

    还进一步改为:

    还有罗曼·艾利扎洛夫的一些有趣的视频:


    您遇到了臭名昭著的“”问题。这两个世界实际上是分离的,虽然可以添加一个将它们统一起来的表面层,但不能以零性能成本实现。这是非常基本的,即使假设您的
    suspend
    块从未真正挂起,并且包装层利用了这一假设,甚至没有在其上使用
    runBlocking
    ,您仍将付出“准备挂起”的代价。不过,代价并不高:这意味着每次
    suspend-fun
    调用都要创建一个小对象,保存通常驻留在线程本机调用堆栈上的数据。在您的例子中,只有外部块是可挂起的,因此这只是一个这样的对象

    runBlocking
    在调用它的线程上运行协程,它将在同一线程上同步完成,除非它挂起自己。因此,在
    suspend
    块中有一些同步代码的情况下,线程协调不会对性能造成额外的影响


    如果协同程序确实挂起了自身,那么必须有一些外部工作线程对允许协同程序恢复的事件作出反应,并且该线程与原始
    runBlocking
    线程之间必须有一些协调。这是一个基本的机制,无论是否有协同程序。

    您遇到了臭名昭著的“”问题。这两个世界实际上是分离的,虽然可以添加一个将它们统一起来的表面层,但不能以零性能成本实现。这是非常基本的,即使假设您的
    suspend
    块从未真正挂起,并且包装层利用了这一假设,甚至没有在其上使用
    runBlocking
    ,您仍将付出“准备挂起”的代价。不过,代价并不高:这意味着每次
    suspend-fun
    调用都要创建一个小对象,保存通常驻留在线程本机调用堆栈上的数据。在您的例子中,只有外部块是可挂起的,因此这只是一个这样的对象

    runBlocking
    在调用它的线程上运行协程,它将在同一线程上同步完成,除非它挂起自己。因此,在
    suspend
    块中有一些同步代码的情况下,线程协调不会对性能造成额外的影响

    如果协同程序确实挂起了自身,那么必须有一些外部工作线程对允许协同程序恢复的事件作出反应,并且该线程与原始
    runBlocking
    线程之间必须有一些协调。这是一个基本的机制,无论是否有协同程序

    suspend fun <R> mapAsync(block: suspend (T) -> R): Result<R> { ... }
    
    fun <R> map(block: (T) -> R): Result<R> =
        runBlocking { mapAsync { block(it) } }