Sono diviso tra design orientato agli oggetti e design basato sul vettore. Adoro le capacità, la struttura e la sicurezza che gli oggetti danno 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 basati su vettori come Matlab o numpy in Python.
Ecco un pezzo di codice che ho scritto per illustrare il mio punto
Problema: aggiunta di numeri di volatilità di rimorchio. Se xey sono due numeri di volatilità, la somma della volatilità è (x ^ 2 + y ^ 2) ^ 0,5 (presupponendo determinate condizioni matematiche ma 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 genere:
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 a Python, __add__
è solo una funzione che sovrascrive l' +
operatore)
Diciamo che aggiungo liste di rimorchio 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 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 fornito non includono affatto il tempo di inizializzazione dell'oggetto, è solo il codice di aggiunta che è stato cronometrato. Se eseguo la stessa cosa usando array intorpiditi:
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 volatilità nel modo sbagliato, ma il metodo vettoriale è così follemente veloce! Esiste un design in cui posso ottenere entrambi? Sono sicuro che molti di voi si sono imbattuti in scelte progettuali simili, come ci sono riuscito?
La scelta della lingua qui è irrilevante. So che molti di voi consiglierebbero l'uso di C ++ o Java, e il codice potrebbe comunque funzionare più velocemente dei linguaggi basati su vettori. Ma non è questo il punto. Devo usare Python, perché ho una serie di librerie non disponibili in altre lingue. Questo è il mio vincolo. Ho bisogno di 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!