私はオブジェクト指向とベクターベースのデザインの間で引き裂かれています。オブジェクトがアーキテクチャ全体に与える能力、構造、安全性が大好きです。しかし同時に、速度は私にとって非常に重要であり、配列に単純なフロート変数があると、MatlabやPythonのnumpyなどのベクトルベースの言語/ライブラリで非常に役立ちます。
これが私のポイントを説明するために書いたコードです
問題:トウのボラティリティ値を追加します。xとyが2つのボラティリティ数である場合、ボラティリティの合計は(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のSeriesはインデックス付きのリストのようなものです)次に、2つを追加します。
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を間違った方法で追加することのない多くのセキュリティを提供しますが、vectorメソッドは非常に高速です!両方を入手できるデザインはありますか?多くの人が似たようなデザインの選択に出くわしたと思いますが、どうやってそれを解決したのですか?
ここでの言語の選択は重要ではありません。多くの場合、C ++またはJavaを使用することをお勧めします。コードは、ベクターベースの言語よりも高速に実行される可能性があります。しかし、それはポイントではありません。Pythonを使用する必要があるのは、他の言語では使用できないライブラリが多数あるためです。それが私の制約です。その中で最適化する必要があります。
そして、多くの人が並列化やgpgpuなどを提案することを知っています。しかし、最初にシングルコアのパフォーマンスを最大化したいので、それからコードの両方のバージョンを並列化できます。
前もって感謝します!