我正在为我的应用程序问题寻找解决方法。
我的应用程序正在生成一百万个点的图表,为此,我要保存一个字符串,其中所有点都用会议室数据库中的空白分隔。
话虽这么说,我正在加载这个点的字符串,使用mapIndex将其拆分为在所有点上放置一个索引,如下所示:
val map = mutableMapOf<Float, Float>()
signal.split(" ").mapIndexed { index, signal ->
signal.toFloatOrNull()?.let { floatSignal ->
map[index.toFloat()] = floatSignal
}
}
使用此代码,我可以在图表上显示所有点,但是当处理一百万个点(超过三秒)时,此操作mapIndexed太慢了
我的问题是,有一种方法可以在多线程上拆分mapIndexed然后加入结果?抱歉,如果有点难以理解,我不是母语人士
答案 0 :(得分:1)
并行运行map
的问题是您可能会丢失列表的顺序。这是forEach
循环的示例,该循环将并行执行
import java.util.*
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
private fun getExecutor(threads: Int) = Executors.newFixedThreadPool(threads)
private fun ExecutorService.run(runnables: List<() -> Unit>) {
val jobs = runnables.map {
submit(it)
}
jobs.forEach {
it.get()
}
}
private val _executorMap = mutableMapOf<Int, ExecutorService>()
fun <T> Iterable<T>.forEachParallel(threads: Int = Runtime.getRuntime().availableProcessors(), block: (T) -> Unit) {
val executor = _executorMap.getOrPut(threads) { getExecutor(threads) }
val list: List<() -> Unit> = (0 until size).map { i ->
{ block(get(i)) }
}
executor.run(list)
}
或者,您可以使用RxJava
private val _executorMap = mutableMapOf<Int, Scheduler>()
private fun getScheduler(threads: Int) =
_executorMap.getOrPut(threads) { Schedulers.from(Executors.newFixedThreadPool(threads)) }
fun <T> Iterable<T>.forEachParallel(threads: Int = Runtime.getRuntime().availableProcessors(), block: (T) -> Unit) {
Flowable.fromIterable(this)
.parallel(threads)
.runOn(getScheduler(threads))
.map(block)
.sequential()
.blockingSubscribe()
如果您确实需要此命令,则可以轻松地修改这2个功能以跟踪索引。您可以像这样使用它:
bigList.forEachParallel {
val result = someComputation(it)
newList.add(result)
}