3

オブジェクト指向とベクターベースのデザインの間で迷っています。オブジェクトが建築全体に与える能力、構造、安全性が大好きです。しかし同時に、速度は私にとって非常に重要であり、配列に単純な float 変数を持つことは、Matlab や Python の numpy などのベクトルベースの言語/ライブラリで本当に役立ちます。

ここに私の要点を説明するために書いたコードがあります

問題: 2 つのボラティリティの数値を追加する。x と y が 2 つのボラティリティの数値である場合、ボラティリティの合計は (x^2 + y^2)^0.5 です (特定の数学的条件を前提としていますが、ここでは重要ではありません)。

私はこの操作を非常に高速に実行したいと考えています。同時に、人々が間違った方法 (x+y) でボラティリティを追加しないようにする必要があります。これらは両方とも重要です。

OO ベースの設計は次のようになります。

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は「+」演算子をオーバーライドする単なる関数です)

ボラティリティ値の2つのリストを追加するとしましょう

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 を追加することがないように、多くのセキュリティを提供してくれますが、ベクトルの方法は非常に高速です! 両方手に入るデザインはありますか?多くの人が似たようなデザインの選択に出くわしたと思いますが、どのように解決しましたか?

ここでの言語の選択は重要ではありません。多くの人が C++ または Java を使用するようアドバイスすることは知っていますが、いずれにせよ、コードはベクトル ベースの言語よりも高速に実行される可能性があります。しかし、それは重要ではありません。他の言語では利用できないライブラリのホストがあるため、Python を使用する必要があります。それが私の制約です。その中で最適化する必要があります。

そして、多くの人が並列化や gpgpu などを提案することを知っています。しかし、私は最初にシングル コアのパフォーマンスを最大化したいと考えています。それから、両方のバージョンのコードを並列化できます。

前もって感謝します!

4

2 に答える 2

3

これらのケースの考えられる解決策は一歩後退することです: 個々の値をオブジェクトとして表現する必要があるか、または表現したいですか? オブジェクトが の配列全体 (またはシリーズ) である場合はどうなりますVolatileか? 両方の長所を活用できます。

個々のオブジェクトに何らかの用途がある場合でも、フライウェイト パターンVolatileを実装できます。この場合、オブジェクトは配列内の位置の単なるラッパーであり、すべてのメソッドが配列で動作します。Volatile

于 2013-06-04T11:53:36.877 に答える
3

ベクトル化された操作の上に、抽象化、カプセル化、コードの再利用などを (OOP またはその他の方法で) 行うことができます。適切な粒度を選択する必要があります。ベクトル化された実装と一致するように、ユニットの抽象化 (オブジェクト) は複数の値にする必要があります。私の知る限り、ボラティリティの複数形はありませんが、特定のユースケースでは、とにかくより適切な用語があるかもしれません(ボラティリティ値のセットは何を意味しますか?)。

はい、これは、パフォーマンスの問題が抽象化と API に影響を与えることを意味します (ただし、とにかく常に発生します)。いいえ、その影響は (必ずしも) 抽象化の削減ではなく、漏れやすい抽象化でもありません。抽象化の形を変えるだけです。実際、一度にすべての値を操作するだけであれば、残りのコードにとってより便利な API になる可能性さえあります。

于 2013-06-04T11:56:06.427 に答える