การเขียนโปรแกรมเชิงวัตถุเทียบกับเวกเตอร์


14

ฉันขาดการออกแบบเชิงวัตถุและเชิงเวกเตอร์ ฉันชอบความสามารถโครงสร้างและความปลอดภัยที่วัตถุมอบให้กับสถาปัตยกรรมทั้งหมด แต่ในขณะเดียวกันความเร็วนั้นสำคัญมากสำหรับฉันและการมีตัวแปรลอยแบบง่าย ๆ ในอาเรย์ช่วยในภาษา / ไลบรารีที่ใช้เวกเตอร์เช่น Matlab หรือ numpy ใน Python

นี่คือส่วนหนึ่งของรหัสที่ฉันเขียนเพื่ออธิบายจุดของฉัน

ปัญหา: การเพิ่มหมายเลขความผันผวนของ Tow หาก x และ y เป็นสองตัวเลขความผันผวนผลรวมของความผันผวนคือ (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))) 

(นอกเหนือจาก: อีกครั้งชุดใน 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 ให้ความปลอดภัยแก่ฉันมากมายซึ่งผู้คนจะไม่เพิ่มความผันผวนในทางที่ผิด แต่วิธีการของเวกเตอร์นั้นเร็วมาก มีการออกแบบที่ฉันสามารถรับทั้งสองได้หรือไม่? ฉันแน่ใจว่าคุณหลายคนเลือกใช้การออกแบบที่คล้ายกันคุณทำงานออกมาได้อย่างไร?

การเลือกใช้ภาษาที่นี่ไม่สำคัญ ฉันรู้ว่าคุณหลายคนแนะนำให้ใช้ C ++ หรือ Java และรหัสอาจทำงานเร็วกว่าภาษาที่ใช้เวกเตอร์อยู่ดี แต่ไม่ thats จุด. ฉันต้องใช้ Python เพราะฉันมีโฮสต์ของไลบรารีที่ไม่สามารถใช้งานได้ในภาษาอื่น นั่นคือข้อ จำกัด ของฉัน ฉันต้องการเพิ่มประสิทธิภาพภายใน

และฉันก็รู้ว่าผู้คนจำนวนมากจะแนะนำให้ใช้การขนาน, gpgpu ฯลฯ แต่ฉันต้องการเพิ่มประสิทธิภาพการทำงานแบบแกนเดียวก่อนและจากนั้นฉันสามารถขนานทั้งสองรุ่นของรหัส

ขอบคุณล่วงหน้า!


3
วิธีที่เกี่ยวข้องอย่างใกล้ชิดเพื่อคิดเกี่ยวกับปัญหานี้: คุณควรใช้โครงสร้างของอาร์เรย์ (SoA) หรืออาร์เรย์ของโครงสร้าง (AoS) สำหรับการทำงานหรือไม่ ด้วยการใช้ SOA ให้ง่ายขึ้นในการทำให้เป็น vectorize และ AoS จะเป็นมิตรกับ OOP ในภาษาส่วนใหญ่
Patrick

ใช่ @Patrick ถ้าคุณเห็นคำตอบแรกฉันคิดว่า Bart ให้ตัวอย่างที่เป็นประโยชน์กับจุดที่คุณกำลังทำอยู่ ฉันถูกไหม? ฉันสังเกตว่าคุณพูดภาษาเกือบทุกภาษาดังนั้นทั้งสองภาษาจึงมีประสิทธิภาพใกล้เคียงกัน?
Ramanuj Lal

คำตอบ:


9

อย่างที่คุณเห็นวิธี OOP ให้ความปลอดภัยแก่ฉันมากมายซึ่งผู้คนจะไม่เพิ่มความผันผวนในทางที่ผิด แต่วิธีการของเวกเตอร์นั้นเร็วมาก มีการออกแบบที่ฉันสามารถรับทั้งสองได้หรือไม่? ฉันแน่ใจว่าคุณหลายคนเลือกใช้การออกแบบที่คล้ายกันคุณทำงานออกมาได้อย่างไร?

ออกแบบวัตถุที่ใหญ่กว่า Pixelวัตถุไม่มีพักหายใจสำหรับ parallelized ห่วงหรือภาพ GPU แปลงหรืออะไรอย่างนั้น Imageไม่ให้ไว้มันไม่ต้องไปผ่านอุปสรรคของเล็กที่Pixelวัตถุที่จะได้รับข้อมูล


5

นี่เป็นหนึ่งในพื้นที่ที่เป็นไปไม่ได้ที่จะให้คำตอบที่ชัดเจนเพราะมันเกี่ยวข้องกับการแลกเปลี่ยน ตามที่คุณค้นพบว่าทั้ง OO และเวกเตอร์นั้นดีกว่าเสมอ แต่ทุกอย่างขึ้นอยู่กับการใช้งานซอฟต์แวร์

คุณสามารถลองผสมผสานสิ่งที่ดีที่สุดทั้งสองอย่างเข้าด้วยกันและสร้างทั้งVolatilityวัตถุและVolatilitySeriesวัตถุโดยที่แนวคิดที่สองแสดงถึงชุดความผันผวนของวัตถุ แต่ภายในใช้วิธีการจัดเก็บที่เหมาะสมกว่าสำหรับการคำนวณเวกเตอร์ (โครงสร้างของอาร์เรย์) . จากนั้นคุณเพียงแค่ต้องให้ความรู้แก่ผู้ใช้ของคุณว่าการใช้VolatilitySeriesนั้นดีกว่าSeries(Volatility)มาก


ขอบคุณ Bart นั่นเป็นความคิดที่ดี ในความเป็นจริงฉันได้ไปในการออกแบบปัจจุบันของฉันในบางส่วนที่วัตถุบางอย่างเช่นจำนวนเงินถูกออกแบบใหม่ด้วยวิธีการที่ แต่ในไม่ช้าฉันก็รู้ว่ารหัสของฉันกลายเป็นทาสของโครงสร้างข้อมูลนั้น ยกตัวอย่างเช่นถ้าฉันมีสิ่งVolatilitySeriesที่คุณแนะนำฉันไม่สามารถมีlistหรือtupleหรือ (สมมติว่าคุณคุ้นเคยกับงูหลาม) DataFrameรายการความผันผวน นั่นทำให้ฉันรำคาญเพราะสถาปัตยกรรมของฉันไม่ค่อยดีนักและผลประโยชน์ก็ค่อย ๆ เลือนหายไปครู่หนึ่ง และนั่นคือสิ่งที่ทำให้ฉันมาที่นี่ :)
Ramanuj Lal

ปัญหาอื่น ๆ คือไม่มีอะไรหยุดทุกคนที่จะเขียนรหัสเช่นvolatilitySeries[0] + 3.0ซึ่งจะผิด เมื่อคุณดิ้นค่าจากVolatilitySeriesคุณสามารถไปบ้าดีเดือดดังนั้นความปลอดภัยเป็นเพียงช่วงสั้น ๆ ในสภาพแวดล้อมแบบ polymorphic ที่ผู้คนไม่ได้ตระหนักถึงการใช้คลาสที่แน่นอนนี่เป็นไปได้สูง และคุณรู้ว่าคุณสามารถให้ความรู้แก่ผู้ใช้ของคุณได้มาก ฉันรู้ว่าคุณจะพูดว่าเฮ้ฉันสามารถทำสิ่งเดียวกันได้ถ้าฉันดิ้นออกVolatility.valueแต่อย่างน้อยผู้ใช้ก็ตระหนักว่าตอนนี้เขากำลังใช้ค่าพิเศษ
Ramanuj Lal

บางคนอาจแนะนำว่าแทนที่ฟังก์ชั่นปกติทั้งหมดที่สืบทอดมาจากSeriesในVolatilitySeriesแต่ที่เอาชนะวัตถุประสงค์ทั้งหมด ดังนั้นสิ่งที่ฉันได้เรียนรู้จากที่จะไปเส้นทางที่เป็นว่ามีวัตถุเท่านั้นจริงๆทำงานออกในระยะยาวถ้าแต่ละเซลล์เป็นประเภทVolatilitySeries Volatility
Ramanuj Lal

@RamanujLal: ฉันไม่รู้จักไพ ธ อนมากพอที่จะตัดสินว่าVolatileSeriesวิธีการนั้นเป็นไปได้หรือไม่ หากคุณลองใช้แล้ว แต่ใช้งานไม่ได้แสดงว่าคุณมีทางเลือกที่ยากในการเลือกระหว่างความปลอดภัยและความเร็ว เราไม่สามารถช่วยคุณได้ (เว้นแต่มีคนอื่นมีคำตอบที่ยอดเยี่ยม)
Bart van Ingen Schenau
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.