Saya terpecah antara berorientasi objek dan desain berbasis vektor. Saya suka kemampuan, struktur, dan keamanan yang diberikan benda-benda ke seluruh arsitektur. Tetapi pada saat yang sama, kecepatan sangat penting bagi saya, dan memiliki variabel float sederhana dalam array sangat membantu dalam bahasa berbasis vektor / perpustakaan seperti Matlab atau numpy in Python.
Ini adalah sepotong kode yang saya tulis untuk mengilustrasikan poin saya
Masalah: Menambahkan angka volatilitas Tow. Jika x dan y adalah dua angka volatilitas, jumlah volatilitasnya adalah (x ^ 2 + y ^ 2) ^ 0,5 (dengan asumsi kondisi matematika tertentu tetapi itu tidak penting di sini).
Saya ingin melakukan operasi ini dengan sangat cepat, dan pada saat yang sama saya perlu memastikan bahwa orang tidak hanya menambahkan volatilitas dengan cara yang salah (x + y). Keduanya penting.
Desain berbasis OO akan seperti ini:
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))
(Selain: Bagi mereka yang baru mengenal Python, __add__
hanyalah fungsi yang menimpa +
operator)
Katakanlah saya menambahkan daftar deretan nilai volatilitas
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)))
(Selain: Sekali lagi, Seri dalam Python adalah semacam daftar dengan indeks) Sekarang saya ingin menambahkan keduanya:
t1 = datetime.now()
vs3 = vs1 + vs2
t2 = datetime.now()
print t2-t1
Hanya penambahan berjalan dalam 3,8 detik pada mesin saya, hasil yang saya berikan tidak termasuk waktu inisialisasi objek sama sekali, itu hanya kode penambahan yang telah diatur waktunya. Jika saya menjalankan hal yang sama menggunakan numpy array:
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
Ini berjalan dalam 0,03 detik. Itu lebih dari 100 kali lebih cepat!
Seperti yang Anda lihat, cara OOP memberi saya banyak keamanan sehingga orang tidak akan menambahkan Volatilitas dengan cara yang salah, tetapi metode vektor sangat cepat gila! Apakah ada desain di mana saya bisa mendapatkan keduanya? Saya yakin banyak dari Anda telah mengalami pilihan desain yang serupa, bagaimana Anda mengatasinya?
Pilihan bahasa di sini tidak penting. Saya tahu banyak dari Anda akan menyarankan agar menggunakan C ++ atau Java, dan kode dapat berjalan lebih cepat daripada bahasa berbasis vektor. Tapi bukan itu intinya. Saya perlu menggunakan Python, karena saya memiliki sejumlah perpustakaan yang tidak tersedia dalam bahasa lain. Itu kendala saya. Saya perlu mengoptimalkan di dalamnya.
Dan saya tahu, bahwa banyak orang akan menyarankan paralelisasi, gpgpu dll. Tetapi saya ingin memaksimalkan kinerja single core terlebih dahulu, dan kemudian saya dapat memparalelkan kedua versi kode.
Terima kasih sebelumnya!
sumber
Jawaban:
Desain benda yang lebih besar. Sebuah
Pixel
objek tidak memiliki ruang bernapas untuk loop paralel atau transformasi gambar GPU atau semacamnya. DanImage
asalkan tidak harus melalui penghalangPixel
objek kecil untuk mendapatkan data.sumber
Ini adalah salah satu bidang di mana tidak mungkin untuk memberikan jawaban yang pasti, karena menyangkut pertukaran. Seperti yang Anda ketahui, baik OO, maupun berbasis vektor selalu unggul, tetapi semuanya tergantung pada bagaimana perangkat lunak akan digunakan.
Anda bisa mencoba untuk menggabungkan yang terbaik dari keduanya dan membuat
Volatility
objek danVolatilitySeries
objek, di mana yang kedua secara konseptual mewakili serangkaian objek Volatilitas, tetapi secara internal menggunakan metode penyimpanan yang jauh lebih cocok untuk vectorisasi perhitungan (struktur array) . Maka Anda hanya perlu mendidik pengguna Anda bahwa menggunakanVolatilitySeries
jauh lebih disukaiSeries(Volatility)
.sumber
VolatilitySeries
seperti yang Anda sarankan, maka saya tidak dapat memilikilist
, atau atuple
atau (dengan asumsi Anda terbiasa dengan Python)DataFrame
item volatilitas. Itu mengganggu saya, karena arsitektur saya tidak skala dengan baik, dan manfaat memudar setelah beberapa saat. Dan itulah yang membawaku ke sini :).volatilitySeries[0] + 3.0
, yang akan salah. Setelah Anda meronta-ronta nilai dariVolatilitySeries
, Anda bisa mengamuk, sehingga keamanan hanya berumur pendek. Dalam lingkungan polimorfik di mana orang tidak selalu menyadari kelas yang tepat digunakan, ini sangat mungkin. Dan Anda tahu, Anda hanya bisa mendidik pengguna Anda begitu banyak. Saya tahu Anda akan mengatakan itu, hei saya juga bisa melakukan hal yang sama jika saya keluarVolatility.value
, tetapi Anda tahu, setidaknya pengguna sekarang sadar bahwa dia menggunakan nilai khusus.Series
dalamVolatilitySeries
, tetapi itu mengalahkan seluruh tujuannya. Jadi apa yang saya pelajari dari menempuh jalan itu adalah bahwa memilikiVolatilitySeries
objek hanya benar-benar berhasil dalam jangka panjang jika masing-masing sel bertipeVolatility
.VolatileSeries
pendekatan itu layak. Jika Anda sudah mencobanya dan tidak berhasil, maka Anda memiliki pilihan sulit untuk dibuat antara keamanan dan kecepatan. Kami tidak dapat membantu Anda di sana. (kecuali orang lain memiliki jawaban yang cemerlang)