Estoy dividido entre el diseño orientado a objetos y el diseño basado en vectores. 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 lenguajes / bibliotecas basadas 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 Tow. Si x e y son dos números de volatilidad, la suma de la volatilidad es (x ^ 2 + y ^ 2) ^ 0.5 (suponiendo cierta condición matemática pero eso no es importante aquí).
Quiero realizar esta operación muy rápido, y al mismo tiempo necesito asegurarme de que las personas no solo agreguen la volatilidad de la 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)
Digamos que agrego listas 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 agregar 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, solo el código de adición que se ha 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 forma OOP me da mucha seguridad de que la gente no agregará Volatility de la manera incorrecta, ¡pero el método vectorial es tan 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 idioma aquí es irrelevante. Sé que muchos de ustedes aconsejarí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 ella.
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 paralelizar ambas versiones de código.
¡Gracias por adelantado!