In Scala, si può facilmente fare una mappa in parallelo, forEach, ecc, con:Operazioni parallele sulle collezioni Kotlin?
collection.par.map(..)
Esiste un equivalente in Kotlin?
In Scala, si può facilmente fare una mappa in parallelo, forEach, ecc, con:Operazioni parallele sulle collezioni Kotlin?
collection.par.map(..)
Esiste un equivalente in Kotlin?
La libreria standard Kotlin non ha il supporto per le operazioni parallele . Tuttavia, poiché Kotlin utilizza le classi di raccolta Java standard, è possibile utilizzare l'API di flusso Java 8 per eseguire anche operazioni parallele su raccolte Kotlin.
come si può usare l'API di flusso Java 8 in Kotlin? – LordScone
@LordScone Nello stesso modo in cui lo faresti in Java. E.g .: 'myCollection.parallelStream(). Map {...}. filter {...} ' –
Al momento attuale n. Se si guarda alla official Kotlin comparison to Scala Vedrete
Cose che possono essere aggiunte ai Kotlin tardi:
- collezioni parallele
Non v'è alcun supporto ufficiale in stdlib di Kotlin ancora, ma si potrebbe definire un extension function di imitare 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)
}
Ecco un semplice esempio di utilizzo
val result = listOf("foo", "bar").pmap { it+"!" }.filter { it.contains("bar") }
Se necessario, consente di modificare il threading fornendo il numero di thread o anche uno specifico java.util.concurrent.Executor
. Per esempio.
listOf("foo", "bar").pmap(4, transform = { it + "!" })
prega di notare che questo approccio consente solo di parallelizzare l'operazione map
e non influenza alcun bit a valle. Per esempio. il filter
nel primo esempio verrebbe eseguito a thread singolo. Tuttavia, in molti casi, solo la trasformazione dei dati (ad esempio map
) richiede la parallelizzazione. Inoltre, sarebbe semplice estendere l'approccio dall'alto ad altri elementi dell'API di raccolta di Kotlin.
Non vedo come" destination.add (transform (item)) "è thread-safe. Cosa deve impedire a due thread di chiamare "destination.add" allo stesso tempo, rompendo così roba da quando ArrayList.add() non è un'operazione thread-safe? –
Grazie per il suggerimento. Piuttosto [alcuni] (http://stackoverflow.com/questions/2715983/concurrent-threads-adding-to-arraylist-at-same-time-what-happens) la gente pensa che quando si aggiungono elementi dovrebbe andare bene senza sincronizzazione . Tuttavia, l'ho modificato per utilizzare un elenco sincronizzato per migliorare la sicurezza del thread. –
L'ordine di destinazione potrebbe non essere lo stesso dell'elenco originale –
A partire da Kotlin 1.1, le operazioni parallele possono anche essere espresse in modo abbastanza elegante in termini di coroutines. Ecco pmap
sulle liste:
fun <A, B>List<A>.pmap(f: suspend (A) -> B): List<B> = runBlocking {
map { async(CommonPool) { f(it) } }.map { it.await() }
}
Nota che coroutine sono ancora una funzione sperimentale.
Alcune delle raccolte parallele più veloci in giro provengono da GS-Collections: https://github.com/goldmansachs/gs-collections ... che è possibile utilizzare da Kotlin (come qualsiasi framework di raccolta Java può essere utilizzato) –