Nesne yönelimli ve vektör tabanlı programlama


14

Nesneye yönelik ve vektör tabanlı tasarım arasında kaldım. Nesnelerin tüm mimariye verdiği yetenekleri, yapıyı ve güvenliği seviyorum. Fakat aynı zamanda hız benim için çok önemli ve bir dizide basit değişken değişkenlere sahip olmak Matlab veya Python'daki numpy gibi vektör tabanlı diller / kütüphanelerde gerçekten yardımcı oluyor.

İşte benim açımdan göstermek için yazdığım bir kod parçası

Sorun: Yedekte volatilite sayıları ekleme. X ve y iki volatilite sayısı ise, volatilitenin toplamı (x ^ 2 + y ^ 2) ^ 0.5'tir (belirli matematiksel koşulun varsayılarak, ancak burada önemli değildir).

Bu işlemi çok hızlı yapmak istiyorum ve aynı zamanda insanların uçuculuğu yanlış şekilde eklememelerini sağlamalıyım (x + y). Bunların her ikisi de önemlidir.

OO tabanlı tasarım şöyle bir şey olurdu:

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

(Kenara: Python'da yeni olanlar için __add__, sadece +operatörü geçersiz kılan bir işlevdir )

Diyelim ki oynaklık değerlerinin yedek listelerini ekliyorum

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

(Bir yana: Yine, Python bir dizi bir tür bir dizin listesi) Şimdi ikisini eklemek istiyorum:

t1 = datetime.now()
vs3 = vs1 + vs2
t2 = datetime.now()
print t2-t1

Sadece ekleme makinemde 3.8 saniye içinde çalışıyor, verdiğim sonuçlar nesne başlatma süresini hiç içermiyor, sadece zamanlanmış ekleme kodu. Aynı şeyi numpy dizileri kullanarak çalıştırırsam:

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 saniye içinde çalışır. Bu 100 kat daha hızlı!

Gördüğünüz gibi, OOP yolu, insanların Volatilite'yi yanlış şekilde eklemeyecekleri için çok fazla güvenlik sağlıyor, ancak vektör yöntemi çok hızlı! İkisini de alabileceğim bir tasarım var mı? Birçoğunuzun benzer tasarım seçenekleriyle karşılaştığınızdan eminim, bunu nasıl yaptınız?

Burada dil seçimi önemsizdir. Birçoğunuzun C ++ veya Java kullanmasını tavsiye edeceğini biliyorum ve kod yine de vektör tabanlı dillerden daha hızlı çalışabilir. Ama mesele bu değil. Python kullanmam gerekiyor, çünkü diğer dillerde mevcut olmayan bir dizi kütüphanem var. Bu benim kısıtlamam. İçinde optimizasyon yapmam gerekiyor.

Ve biliyorum, birçok insan paralelleştirme, gpgpu vb. Önerecektir. Ama önce tek çekirdekli performansı en üst düzeye çıkarmak istiyorum ve sonra kodun her iki versiyonunu da paralelleştirebilirim.

Şimdiden teşekkürler!


3
Bu sorunu düşünmenin yakından ilişkili bir yolu: Performans için diziler (SoA) veya bir dizi yapı (AoS) kullanmalı mısınız? SoA'nın vektörleştirilmesi daha kolay ve AoS çoğu dilde daha OOP dostu.
Patrick

evet @ Patrick, ilk cevabı görürseniz bence Bart sizin bahsettiğiniz noktaya pratik bir örnek verdi. Haklı mıyım? Çoğu dili söylediğinizi fark ediyorum , bu yüzden her ikisinin de performans açısından yakın olduğu diller var mı?
Ramanuj Lal

Yanıtlar:


9

Gördüğünüz gibi, OOP yolu, insanların Volatilite'yi yanlış şekilde eklemeyecekleri için çok fazla güvenlik sağlıyor, ancak vektör yöntemi çok hızlı! İkisini de alabileceğim bir tasarım var mı? Birçoğunuzun benzer tasarım seçenekleriyle karşılaştığınızdan eminim, bunu nasıl yaptınız?

Daha büyük nesneler tasarlayın. Bir Pixelnesnenin paralelleştirilmiş bir döngü veya GPU görüntü dönüşümleri veya bunun gibi herhangi bir şey için solunum odası yoktur. A , verilere ulaşmak Imageiçin ufacık bir Pixelnesnenin bariyerinden geçmek zorunda kalmazsa .


5

Bu, kesin cevaplar vermenin imkansız olduğu alanlardan biridir, çünkü bir değiş tokuş ile ilgilidir. Bildiğiniz gibi, ne OO ne de vektör tabanlı her zaman üstündür, ancak hepsi yazılımın nasıl kullanılacağına bağlıdır.

Her ikisinin de en iyisini birleştirmeye çalışabilir ve hem bir Volatilitynesneyi hem de bir nesneyi yaratabilirsiniz VolatilitySeries, burada ikincisi kavramsal olarak bir Volatilite Serisi serisini temsil eder, ancak dahili olarak hesaplamaları vektörlemek için çok daha uygun bir depolama yöntemi kullanır (dizilerin yapısı). . Daha sonra, kullanıcılarınızı kullanmanın VolatilitySeriesçok daha tercih edilir olduğunu eğitmeniz gerekir Series(Volatility).


Teşekkürler Bart, bu iyi bir fikir. Aslında, parasal miktarlar gibi bazı nesnelerin bu şekilde yeniden tasarlandığı parçalardaki mevcut tasarımımda bu şekilde gittim. Ama yakında kodumun belirli veri yapısının kölesi olduğunu fark ettim. Örneğin VolatilitySeries, önerdiğiniz gibi bir a varsa, o zaman bir listveya bir tupleveya (Python aşina olduğunuzu varsayarak) bir DataFramevolatilite öğeleri alamıyorum . Bu beni rahatsız ediyor, çünkü o zaman mimarim iyi ölçeklenmiyor ve faydalar bir süre sonra kayboluyor. Beni buraya getiren de bu :).
Ramanuj Lal

Diğer sorun ise, hiçbir şeyin kimsenin böyle bir kod yazmasını durdurmamasıdır volatilitySeries[0] + 3.0, ki bu yanlış olacaktır. Değerleri ortadan VolatilitySerieskaldırdığınızda, çılgına dönebilirsiniz, böylece güvenlik sadece kısa ömürlüdür. İnsanların kullanılan sınıfın her zaman farkında olmadıkları bir polimorfik ortamda, bu oldukça mümkündür. Ve biliyorsunuz, yalnızca kullanıcılarınızı çok fazla eğitebilirsiniz. Bunu söyleyeceğinizi biliyorum, hey aynı şeyi yapabilirsem aynı şeyi yapabilirim Volatility.value, ama biliyorsunuz, en azından kullanıcı şimdi özel bir değer kullandığının farkında.
Ramanuj Lal

Bazıları, Seriesiçinde miras alınan tüm bu normal işlevlerin geçersiz kılınmasını önerebilir VolatilitySeries, ancak bu, tüm amacı bozar. Bu yolda ilerlediğimden öğrendiğim şey, bir VolatilitySeriesnesneye sahip olmanın , tek tek hücreler tipteyse uzun vadede gerçekten işe yaramasıdır Volatility.
Ramanuj Lal

@RamanujLal: VolatileSeriesYaklaşımın uygulanabilir olup olmadığını belirlemek için yeterince piton bilmiyorum . Zaten denediyseniz ve işe yaramadıysa, güvenlik ve hız arasında seçim yapmak için zor bir seçiminiz var. Orada size yardım edemeyiz. (bir başkasının parlak bir cevabı yoksa)
Bart van Ingen Schenau
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.