In che modo le prestazioni delle operazioni di array Python / Numpy si adattano all'aumentare delle dimensioni dell'array?


21

Come si adattano le matrici Python / Numpy all'aumentare delle dimensioni dell'array?

Questo si basa su alcuni comportamenti che ho notato durante il benchmarking del codice Python per questa domanda: Come esprimere questa espressione complicata usando le sezioni intorpidite

Il problema riguardava principalmente l'indicizzazione per popolare un array. Ho scoperto che i vantaggi dell'utilizzo delle versioni (non molto buone) di Cython e Numpy su un loop Python variavano a seconda della dimensione degli array coinvolti. Sia Numpy che Cython presentano un vantaggio prestazionale crescente fino a un certo punto (da qualche parte intorno a per Cython e per Numpy sul mio laptop), dopo di che i loro vantaggi sono diminuiti (la funzione Cython è rimasta la più veloce).N=500N=2000

Questo hardware è definito? In termini di lavoro con array di grandi dimensioni, quali sono le migliori pratiche a cui si dovrebbe aderire per il codice in cui le prestazioni sono apprezzate?

Grafico del tempo di esecuzione relativo al codice in loop per implementazioni vettoriali e Cython

Questa domanda ( perché non è la mia matrice-vettore Moltiplicazione Scaling? ) Può essere correlato, ma io sono interessato a sapere di più su come i diversi modi di trattare gli array in Python scala rispetto all'altro.


Hai provato numexpr ? C'è anche, ad esempio, questo discorso che punta a blosc e CArray , tutti pensati per accelerare ulteriormente le cose (e possibilmente bypassando le limitazioni della larghezza di banda della memoria).
0 0

1
Puoi pubblicare il codice utilizzato per il profilo. Probabilmente ci sono alcune cose che stanno succedendo qui.
meawoppl

Risposte:


5

416KB

def timeit(size):
     t0 = time.time()
     for _ in xrange(10):
         np.random.random(size)
     return time.time() - t0

sizes = np.logspace(1, 6, 40)
times = [timeit(s) for s in sizes]

Ci sono alcune cose sbagliate in questo benchmark, per cominciare, non sto disabilitando la garbage collection e sto prendendo la somma, non il momento migliore, ma sopporto.

800064KB

Uno dovrebbe preoccuparsi della dimensione della cache? Come regola generale, dico di no. L'ottimizzazione per esso in Python significa rendere il codice molto più complicato, per guadagni di prestazioni dubbi. Non dimenticare che gli oggetti Python aggiungono diversi overhead difficili da tracciare e prevedere. Posso solo pensare a due casi in cui questo è un fattore rilevante:

  • Operazioni di base su array di grandi dimensioni (come valutare un polinomio), limitato dalla larghezza di banda della memoria. Usa Numexpr o (se i dati sono molto più grandi) Pytables . Sono ottimizzati per tenere conto della dimensione della cache tra le altre ottimizzazioni.
  • Codice critico per le prestazioni: se vuoi spremere ogni microsecondo, non dovresti usare Python in primo luogo. Scrivere Cython vettoriale e lasciare il compilatore fare ciò che fa meglio è probabilmente la strada indolore da percorrere.

Nei commenti, Evert ha menzionato CArray. Si noti che, anche funzionando, lo sviluppo si è interrotto ed è stato abbandonato come progetto autonomo. La funzionalità verrà invece inclusa in Blaze , un progetto in corso per creare un "Numpy di nuova generazione".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.