协程值得与类型映射一起使用吗?

时间:2019-08-28 12:59:32

标签: android kotlin android-livedata android-jetpack kotlin-coroutines

是否值得调用协程以执行类型映射操作?还是太多的代码膨胀和/或开销?

因此,情况如下:

  • 回购返回LiveData<List<A>>

  • 的对象
  • 视图需要类型为LiveData<<List<GUI_A>>

  • 的对象
  • ViewModel通过使用LiveData<GUI_A>和来自仓库的源Transformations.map来公开LiveData<A>


Transformations.map代码看起来像这样

fun doSomethingWithRepoData(repoData: LiveData<List<A>>): LiveData<List<GUI_A>> =
    Transformations.map(repoData) { 
        it.map { GUI_A.fromRepoObject(it) }
    }

函数fromRepoObject仅将属性从第一个对象映射到第二个对象的新实例。


这个想法是在map函数中使用协程以提高性能;但我不知道这是否值得麻烦:

fun doSomethingWithRepoData(repoData: LiveData<List<A>>): LiveData<List<GUI_A>> =
    Transformations.map(repoData) { 
        it.map { async { GUI_A.fromRepoObject(it) } }
          .map { it.await() }
    }

1 个答案:

答案 0 :(得分:0)

我讨厌它的确切答案是取决于

切换线程的上下文不是免费提供的,并且这样做有一些累积的开销,因此在考虑一件事或另一件事之前,您必须注意数据的大小。

  • 映射15个元素?可能不值得。
  • 映射1000?也许!他们有嵌套的列表和地图也应该被映射吗?
  • 映射1_000_000?肯定!

我们还应该注意我们的映射实现。

给出的例子:

fun doSomethingWithRepoData(repoData: LiveData<List<A>>): LiveData<List<GUI_A>> =
    Transformations.map(repoData) { 
        it.map { async { GUI_A.fromRepoObject(it) } }
          .map { it.await() }
    }

这是不要这样做。

您看到了; LiveData确保观察LiveData的代码正在主线程上运行。一方面,这很好,因为它可以确保主要的安全性;另一方面,在这种情况下,它是“不好的”,因为主线程在推送值之前等待所有协程完成映射操作。

假设我们处于ViewModel,那么一种更聪明的方法可能是:

class SampleVM: ViewModel(){

    fun doSomethingWithRepoData(repoData: LiveData<List<A>>): LiveData<List<GUI_A>> = 
    Transformations.switchMap(repoData) { listA ->
        val result = MutableLiveData<List<GUI_A>>()
        // Don't block the UI thread by running in a coroutine
        viewModelScope.launch {
            listA
                 // Parallelize computation
                 .map { async(Dispatchers.Default) { GUI_A.fromRepoObject(it) }
                 // The viewModelScope job will await for all coroutines to finish mapping
                 .map { it.await() }
                 // Post the result to into the live data
                 .let { result.postValue(it) }
        }

        result
    }


}