Operaciones paralelas en las collections de Kotlin?

En Scala, uno puede hacer fácilmente un map paralelo, para cada uno, etc., con:

collection.par.map(..) 

¿Hay un equivalente en Kotlin?

La biblioteca estándar de Kotlin no tiene soporte para operaciones paralelas. Sin embargo, dado que Kotlin usa las classs de colección estándar de Java, puede usar la API de flujo de Java 8 para realizar operaciones paralelas en las collections de Kotlin también.

Todavía no hay soporte oficial en stdlib de Kotlin, pero podría definir una function de extensión para imitar a par.map :

 fun <T, R> Iterable<T>.pmap( numThreads: Int = Runtime.getRuntime().availableProcessors() - 2, exec: ExecutorService = Executors.newFixedThreadPool(numThreads), transform: (T) -> R): List<R> { // default size is just an inlined version of kotlin.collections.collectionSizeOrDefault val defaultSize = if (this is Collection<*>) this.size else 10 val destination = Collections.synchronizedList(ArrayList<R>(defaultSize)) for (item in this) { exec.submit { destination.add(transform(item)) } } exec.shutdown() exec.awaitTermination(1, TimeUnit.DAYS) return ArrayList<R>(destination) } 

( fuente de Github )

Aquí hay un ejemplo de uso simple

 val result = listOf("foo", "bar").pmap { it+"!" }.filter { it.contains("bar") } 

Si es necesario, permite ajustar el subprocesamiento proporcionando el número de subprocesss o incluso un java.util.concurrent.Executor específico. P.ej

 listOf("foo", "bar").pmap(4, transform = { it + "!" }) 

Tenga en count que este enfoque solo permite paralelizar la operación del map y no afecta a ningún bit en sentido descendente. Por ejemplo, el filter en el primer ejemplo se ejecutará con un solo subprocess. Sin embargo, en muchos casos solo la transformación de datos (es decir, el map ) requiere paralelización. Además, sería sencillo extender el enfoque desde arriba a otros elementos de la API de recostackción de Kotlin.

A partir de Kotlin 1.1, las operaciones paralelas también se pueden express con bastante elegancia en términos de corutinas . Aquí está pmap en las lists:

 fun <A, B>List<A>.pmap(f: suspend (A) -> B): List<B> = runBlocking { map { async(CommonPool) { f(it) } }.map { it.await() } } 

Tenga en count que las corrutinas son todavía una característica experimental.

En el momento presente no. Si miras la comparación oficial de Kotlin con Scala , verás

Cosas que pueden agregarse a Kotlin más tarde:

  • Colecciones paralelas