객체 지향 대 벡터 기반 프로그래밍


14

객체 지향 디자인과 벡터 기반 디자인 사이에서 찢어졌습니다. 나는 객체가 전체 아키텍처에 부여하는 능력, 구조 및 안전을 좋아합니다. 그러나 동시에 속도는 나에게 매우 중요하며 배열에 간단한 float 변수를 사용하면 Matlab 또는 Python의 numpy와 같은 벡터 기반 언어 / 라이브러리에서 실제로 도움이됩니다.

여기 내 요점을 설명하기 위해 작성한 코드가 있습니다.

문제 : 견인 변동성 수치 추가. 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__를 재정의하는 함수 일뿐입니다 +)

변동성 가치의 견인 목록을 추가한다고 가정 해 봅시다.

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))) 

(제외 : 다시 말하지만, 파이썬의 시리즈는 인덱스가있는 목록입니다.) 이제 두 가지를 추가하고 싶습니다.

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 방식은 사람들이 휘발성을 잘못된 방식으로 추가하지 않을 것이라는 많은 보안을 제공하지만 벡터 방법은 너무 빠릅니다! 둘 다 얻을 수있는 디자인이 있습니까? 많은 디자인이 비슷한 디자인을 선택했다고 확신합니다. 어떻게 해결 했습니까?

여기서 언어의 선택은 중요하지 않습니다. C ++ 또는 Java를 사용하는 것이 좋습니다. 어쨌든 코드는 벡터 기반 언어보다 빠르게 실행될 수 있습니다. 그러나 그것은 요점이 아닙니다. 다른 언어로는 사용할 수없는 라이브러리가 많기 때문에 Python을 사용해야합니다. 이것이 나의 제약입니다. 그 안에서 최적화해야합니다.

그리고 많은 사람들이 병렬화, gpgpu 등을 제안한다는 것을 알고 있습니다. 그러나 먼저 단일 코어 성능을 최대화하고 나서 두 버전의 코드를 병렬화 할 수 있습니다.

미리 감사드립니다!


3
이 문제에 대해 밀접하게 관련된 방법 : 성능을 위해 배열 구조 (SoA) 또는 배열 구조 (AoS)를 사용해야합니까? SoA는 벡터화하기 쉽고 AoS는 대부분의 언어에서 OOP 친화적입니다.
Patrick

예 @ 패트릭, 당신이 첫 번째 대답을 보면, 바트는 당신이 만들고있는 요점의 실제적인 예를 제시했다고 생각합니다. 내가 맞아? 나는 당신이 대부분의 언어 를 말하는 것을 알고 있습니다. 그래서 둘 다 성능이 비슷한 언어가 있습니까?
Ramanuj Lal

답변:


9

보시다시피, OOP 방식은 사람들이 휘발성을 잘못된 방식으로 추가하지 않을 것이라는 많은 보안을 제공하지만 벡터 방법은 너무 빠릅니다! 둘 다 얻을 수있는 디자인이 있습니까? 많은 디자인이 비슷한 디자인을 선택했다고 확신합니다. 어떻게 해결 했습니까?

더 큰 물체를 디자인하십시오. Pixel객체는 그런 병렬화 된 루프 또는 GPU 이미지 변환 또는 아무것도에 대한 호흡 공간이 없습니다. 는 Image이 조그마한의의 장벽을 통해 갈 필요가 없습니다 제공된 않는 Pixel데이터에서 얻을 객체입니다.


5

이것은 절충과 관련되어 있기 때문에 결정적인 대답을하기가 불가능한 영역 중 하나입니다. 아시다시피 OO 나 벡터 기반은 항상 우수하지는 않지만 소프트웨어 사용 방법에 따라 다릅니다.

두 가지를 모두 결합하여 Volatility객체와 객체를 만들 수 있습니다. 두 VolatilitySeries번째 객체는 개념적으로 일련의 변동성 객체를 나타내지 만 내부적으로 계산 벡터화에 훨씬 더 적합한 저장 방법을 사용합니다 (배열 구조). . 그런 다음 사용하는 VolatilitySeries것이 훨씬 바람직 하다는 것을 사용자에게 교육시켜야합니다 Series(Volatility).


고마워 바트, 좋은 생각이야. 사실 저는 현재 디자인에서 화폐 금액과 같은 일부 객체가 그런 식으로 재 설계 된 방식으로 진행했습니다. 그러나 곧 내 코드가 특정 데이터 구조의 노예가됨을 깨달았습니다. 예를 들어 내가 VolatilitySeries제안한대로을 가지고 있다면 list, 또는 a ( tuple또는 파이썬에 익숙하다고 가정) DataFrame휘발성 항목을 가질 수 없습니다 . 아키텍처가 확장되지 않기 때문에 이점이 있습니다. 이점은 잠시 후에 사라집니다. 그리고 그것이 나를 여기로 데려온 것입니다 :).
Ramanuj Lal

다른 문제는 누군가가와 같은 코드를 작성하는 것을 방해하지 않는다는 volatilitySeries[0] + 3.0것입니다. 의 값을 수정하면 혼란에 빠질 VolatilitySeries수 있으므로 안전성이 부족합니다. 사람들이 사용되는 정확한 클래스를 항상 인식하지 못하는 다형성 환경에서는 이것이 가능합니다. 알다시피, 당신은 단지 사용자에게 많은 교육을 할 수 있습니다. 나는 당신이 말할 때도 같은 일을 할 수 있다고 말하지만, Volatility.value적어도 사용자는 그가 특별한 가치를 사용하고 있음을 알고 있습니다.
Ramanuj Lal

일부 Series에서는에서 상속받은 모든 일반적인 함수를 재정의한다고 제안 VolatilitySeries하지만 전체 목적 을 무효화합니다 . 제가 그 길을 따라 가면서 배운 VolatilitySeries것은 개별 셀이 유형이라면 장기적으로 만 객체 를 갖는 것이 가능하다는 것입니다 Volatility.
Ramanuj Lal

@RamanujLal : VolatileSeries접근 방식이 가능한지 판단하기에 파이썬을 잘 알지 못합니다 . 이미 시도했지만 작동하지 않으면 안전과 속도 중에서 선택하기가 어렵습니다. 우리는 당신을 도울 수 없습니다. (다른 사람이 훌륭한 답변을하지 않는 한)
Bart van Ingen Schenau 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.