是否值得调用协程以执行类型映射操作?还是太多的代码膨胀和/或开销?
因此,情况如下:
回购返回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() }
}
答案 0 :(得分:0)
我讨厌它的确切答案是取决于。
切换线程的上下文不是免费提供的,并且这样做有一些累积的开销,因此在考虑一件事或另一件事之前,您必须注意数据的大小。
我们还应该注意我们的映射实现。
给出的例子:
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
}
}