Programmazione orientata agli oggetti e vettoriale

13

Sono combattuto tra design orientato agli oggetti e vettoriale. Adoro le capacità, la struttura e la sicurezza che gli oggetti conferiscono all'intera architettura. Ma allo stesso tempo, la velocità è molto importante per me, e avere semplici variabili float in un array aiuta davvero in linguaggi / librerie basate su vettori come Matlab o numpy in Python.

Ecco un pezzo di codice che ho scritto per illustrare il mio punto

Problema: aggiunta dei numeri di volatilità di Tow. Se x e y sono due numeri di volatilità, la somma della volatilità è (x ^ 2 + y ^ 2) ^ 0.5 (presupponendo certe condizioni matematiche ma ciò non è importante qui).

Voglio eseguire questa operazione molto velocemente, e allo stesso tempo devo assicurarmi che le persone non aggiungano semplicemente la volatilità nel modo sbagliato (x + y). Entrambi sono importanti.

Il design basato su OO sarebbe qualcosa del tipo:

from datetime import datetime 
from pandas import *

class Volatility:
    def __init__(self,value):
       self.value = value

    def __str__(self):
       return "Volatility: "+ str(self.value)

    def __add__(self,other):
        return Volatility(pow(self.value*self.value + other.value*other.value, 0.5))

(a parte: per coloro che sono nuovi in Python, __add__ è solo una funzione che sovrascrive l'operatore + )

Diciamo che aggiungo elenchi di valori di volatilità

n = 1000000
vs1 = Series(map(lambda x: Volatility(2*x-1.0), range(0,n)))
vs2 = Series(map(lambda x: Volatility(2*x+1.0), range(0,n))) 

(A parte: ancora una volta, una serie in Python è una specie di elenco con un indice) Ora voglio aggiungere i due:

t1 = datetime.now()
vs3 = vs1 + vs2
t2 = datetime.now()
print t2-t1

Solo l'aggiunta viene eseguita in 3.8 secondi sulla mia macchina, i risultati che ho dato non includono il tempo di inizializzazione dell'oggetto, è solo il codice di addizione che è stato cronometrato. Se eseguo la stessa cosa usando gli array numpy:

nv1 = Series(map(lambda x: 2.0*x-1.0, range(0,n)))
nv2 = Series(map(lambda x: 2.0*x+1.0, range(0,n)))

t3 = datetime.now()
nv3 = numpy.sqrt((nv1*nv1+nv2*nv2))
t4 = datetime.now()
print t4-t3

Funziona in 0,03 secondi. È più di 100 volte più veloce!

Come puoi vedere, il modo OOP mi dà molta sicurezza che le persone non aggiungeranno la volatilità nel modo sbagliato, ma il metodo vettoriale è così follemente veloce! C'è un disegno in cui posso ottenere entrambi? Sono sicuro che molti di voi hanno sperimentato scelte progettuali simili, come avete lavorato?

La scelta della lingua qui è irrilevante. So che molti di voi consiglierebbero di usare C ++ o Java e il codice potrebbe funzionare più velocemente dei linguaggi vettoriali. Ma non è questo il punto. Ho bisogno di usare Python, perché ho una serie di librerie non disponibili in altre lingue. Questo è il mio limite. Devo ottimizzare al suo interno.

E so che molte persone suggerirebbero parallelizzazione, gpgpu, ecc. Ma prima voglio massimizzare le prestazioni single core, quindi posso parallelizzare entrambe le versioni del codice.

Grazie in anticipo!

    
posta Ramanuj Lal 04.06.2013 - 07:10
fonte

2 risposte

8

As you can see, the OOP way gives me a lot of security that people won't be adding Volatility the wrong way, but the vector method is just so crazy fast! Is there a design in which I can get both? I am sure a lot of you have run into similar design choices, how did you work it out?

Progetta oggetti più grandi. Un oggetto Pixel non ha spazio per le trasformazioni di immagini in loop o GPU o qualcosa del genere. Un Image gli ha fornito che non deve passare attraverso la barriera di un oggetto Pixel per ottenere i dati.

    
risposta data 31.12.2015 - 01:29
fonte
5

Questa è una di quelle aree in cui è impossibile dare risposte definitive, perché riguarda un trade-off. Come hai scoperto, né OO, né basato su vettori è sempre superiore, ma tutto dipende da come verrà utilizzato il software.

Potresti provare a combinare il meglio di entrambi e creare sia un oggetto Volatility che un oggetto VolatilitySeries , dove il secondo rappresenta concettualmente una serie di oggetti Volatility, ma internamente utilizza un metodo di archiviazione che è molto più adatto per vettorizzazione dei calcoli (una struttura di array). Quindi devi solo educare i tuoi utenti che l'utilizzo di VolatilitySeries è molto preferibile rispetto a Series(Volatility) .

    
risposta data 04.06.2013 - 10:43
fonte

Leggi altre domande sui tag