Я розривається між об'єктно-орієнтованим та векторним дизайном. Я люблю здібності, структуру та безпеку, які об'єкти надають всій архітектурі. Але в той же час для мене дуже важлива швидкість, і наявність простих змінних плаваючих елементів в масиві дійсно допомагає в векторних мовах / бібліотеках, таких як Matlab або numpy в Python.
Ось фрагмент коду, який я написав, щоб проілюструвати свою думку
Проблема: Додавання номерів нестабільності Tow. Якщо x і y - два числа летючості, сума мінливості становить (x ^ 2 + y ^ 2) ^ 0,5 (якщо припустити певну математичну умову, але це тут не важливо).
Я хочу виконати цю операцію дуже швидко, і в той же час мені потрібно переконатися, що люди не просто додають мінливість неправильно (x + y). І те й інше важливо.
Дизайн на основі ОО був би таким:
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))
(Убік: Для тих, хто не знайомий з Python, __add__
це лише функція, що перекриває +
оператора)
Скажімо, я додаю списки значень летючості
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)))
(Убік: знову ж таки, серія в Python - це свого роду список з індексом) Тепер я хочу додати два:
t1 = datetime.now()
vs3 = vs1 + vs2
t2 = datetime.now()
print t2-t1
Просто додавання працює на 3,8 секунди на моїй машині, результати, які я дав, взагалі не включають час ініціалізації об'єкта, його єдиний код додавання, який був приурочений. Якщо я запускаю те саме, використовуючи 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
Він працює за 0,03 секунди. Це в 100 разів швидше!
Як бачите, спосіб OOP дає мені багато безпеки, що люди не будуть додавати Volatility неправильно, але векторний метод просто так шалено швидко! Чи є дизайн, в якому я можу отримати обидва? Я впевнений, що багато з вас стикалися з подібними варіантами дизайну, як ви це розробили?
Вибір мови тут несуттєвий. Я знаю, що багато хто з вас радить використовувати C ++ або Java, і код може працювати швидше, ніж мови на основі векторних. Але це не сенс. Мені потрібно використовувати Python, оскільки у мене є безліч бібліотек, недоступних іншими мовами. Це моє обмеження. Мені потрібно оптимізувати всередині нього.
І я знаю, що багато людей пропонують паралелізацію, gpgpu тощо. Але я хочу спершу досягти максимальної продуктивності одного ядра, а потім можу паралелізувати обидві версії коду.
Спасибі заздалегідь!