Estoy dividido entre el diseño orientado a objetos y el diseño vectorial. Me encantan las habilidades, la estructura y la seguridad que los objetos dan a toda la arquitectura. Pero al mismo tiempo, la velocidad es muy importante para mí, y tener variables flotantes simples en una matriz realmente ayuda en bibliotecas o lenguajes basados en vectores como Matlab o numpy en Python.
Aquí hay un fragmento de código que escribí para ilustrar mi punto
Problema: Agregar números de volatilidad de remolque. Si x e y son dos números de volatilidad, la suma de la volatilidad es (x ^ 2 + y ^ 2) ^ 0.5 (asumiendo cierta condición matemática pero eso no es importante aquí).
Quiero realizar esta operación muy rápido, y al mismo tiempo debo asegurarme de que las personas no solo agreguen la volatilidad de manera incorrecta (x + y). Ambos son importantes.
El diseño basado en OO sería algo como esto:
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))
(Aparte: para aquellos que son nuevos en Python, __add__
es solo una función que anula el operador +
)
Supongamos que agrego listas de arrastre de valores de volatilidad
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)))
(Aparte: una vez más, una serie en Python es una especie de lista con un índice) Ahora quiero añadir los dos:
t1 = datetime.now()
vs3 = vs1 + vs2
t2 = datetime.now()
print t2-t1
Solo la adición se ejecuta en 3.8 segundos en mi máquina, los resultados que he dado no incluyen el tiempo de inicialización del objeto, es solo el código de adición cronometrado. Si ejecuto lo mismo usando matrices 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
Se ejecuta en 0.03 segundos. ¡Eso es más de 100 veces más rápido!
Como puede ver, la manera de la POO me da mucha seguridad de que la gente no agregará la volatilidad de la manera incorrecta, ¡pero el método de vectores es muy rápido! ¿Hay un diseño en el que pueda obtener ambos? Estoy seguro de que muchos de ustedes se han encontrado con opciones de diseño similares, ¿cómo lo resolvieron?
La elección del lenguaje aquí es inmaterial. Sé que muchos de ustedes recomendarían usar C ++ o Java, y el código puede ejecutarse más rápido que los lenguajes basados en vectores de todos modos. Pero ese no es el punto. Necesito usar Python, porque tengo una gran cantidad de bibliotecas que no están disponibles en otros idiomas. Esa es mi restricción. Necesito optimizar dentro de él.
Y sé que mucha gente sugeriría paralelización, gpgpu, etc. Pero primero quiero maximizar el rendimiento de un solo núcleo y luego puedo paralizar ambas versiones del código.
Gracias de antemano!