La comprensione degli elenchi Python è multi-threading o parallela in qualsiasi modo per impostazione predefinita?

1

Quando scrivo ...

l2 = [my_computation(x) for x in l]

..., mi chiedo se python stia applicando my_computation a ogni x usando tutti i core della mia CPU.

Se no, perché? Esiste un modo semplice per rendere Python parallelizzare la comprensione degli elenchi?

Questo è correlato al comportamento di map() o non lo è affatto?

    
posta ofaurax 17.03.2016 - 10:33
fonte

2 risposte

1

When I write...

l2 = [my_computation(x) for x in l]

..., I wonder if python is applying my_computation to every x using all cores of my CPU.

Il riferimento al linguaggio Python non proibisce esplicitamente né forza esplicitamente la valutazione asincrona, concorrente o parallela:

The comprehension consists of a single expression followed by at least one for clause and zero or more for or if clauses. In this case, the elements of the new container are those that would be produced by considering each of the for or if clauses a block, nesting from left to right, and evaluating the expression to produce an element each time the innermost block is reached.

In effetti, come puoi vedere, in realtà non fornisce nessuna semantica di valutazione . Le due frasi sopra sono l'intera specificazione del comportamento di comprensione.

PEP202 - Comprensione delle liste è ancora meno utile.

If not, why ?

Come puoi vedere, è consentita un'implementazione, ma non è necessario per parallelizzare la comprensione degli elenchi. Tuttavia, parallelizzando è solo corretto se my_computation è referenzialmente trasparente. E capire se è referenzialmente trasparente, equivale a risolvere il problema dell'arresto, ergo impossibile nel caso generale.

È, ovviamente, in casi specifici a volte possibile decidere la trasparenza referenziale, tuttavia, almeno su CPython, l'implementazione Python più popolare, che non sarà di aiuto: CPython non è in grado di eseguire comunque codice Python in parallelo.

Is there a simple way to make python parallelize list comprehensions?

Non che io sappia. Il loro comportamento è criptato nella lingua, non si traduce in messaggi inviati, quindi non c'è nulla che tu possa implementare o sovrascrivere per cambiare il loro comportamento.

Confrontalo con Scala o C #, ad esempio, che hanno una funzione correlata, che è definita come una semplice traduzione sintattica ai messaggi inviati e quindi può essere ignorata. Per esempio. in Scala, l'equivalente sarebbe

for (x ← l) yield myComputation(x)

e questo sarebbe tradotto in

l.map(x ⇒ myComputation(x))

Quindi, puoi cambiare il comportamento fornendo il tuo metodo map , che è esattamente ciò che il Parallel Collections Framework viene fornito con Scala Standard Library fa.

Is this related to the behavior of map() or not at all?

No. Se lo fosse, potresti cambiarlo fornendo il tuo metodo map .

Il modulo concurrent.futures nella libreria standard Python, ad esempio, fornisce il proprio metodo map .

    
risposta data 17.03.2016 - 11:30
fonte
0

Risposta breve: No.

Ci sono due ostacoli:

Il primo è che la comprensione delle liste è basata sull'idea che ogni articolo verrà elaborato in ordine, allo stesso modo ogni volta. Parallelizzando il processo si romperebbe il codice che dipende da quel comportamento. Ciò non significa che non ci potrebbe essere qualcosa di scritto per interrompere il lavoro e passarlo a più thread nei casi in cui non è un problema, ma il secondo ostacolo rende ciò che non vale la pena fare.

Il secondo è che Python in realtà non multithread , che va bene per I lavori con rilegatura I / O ma non forniscono prestazioni aggiuntive quando è necessario eseguire il calcolo.

    
risposta data 17.03.2016 - 11:15
fonte

Leggi altre domande sui tag