2012-10-16 69 views
0

我有一個包含一些類變量的一類:類變量查找VS實例變量查找

c_dict1c_dict2c_dict3

他們都是字典和存儲使用一些的一些值下面的實例變量作爲鍵。

我有這個類的實例幾百,每個具有以下實例變量

i_key1i_key2i_key3i_attr1i_attr2i_attr3

他們前三( i_key*)可以用來查找類變量中的後三個(i_attr*)。換句話說:

self.i_attr1 = MyClass.c_dict1(i_key1) 
self.i_attr2 = MyClass.c_dict2(i_key2) 
self.i_attr3 = MyClass.c_dict3(i_key3) 

我的問題是:

在性能方面,我應該保持實例變量i_attr*本地,或者我應該通過使用類變量c_dict*字典查找訪問它們?很顯然,通過類變量來消除每個實例的三個指針,這可能會節省一些內存,但是這樣做會有什麼重大的速度損失嗎?

+0

我覺得挺奇怪的「場景」。你確定你是以正確的方式做到這一點嗎?沒有一種更簡單的方法來做你想做的事情嗎? – Bakuriu

+0

我想我們需要知道你的程序的目的。什麼是「MyClass」? 「i_key」,「i_attr」和「c_dict」代表什麼? – japreiss

回答

4

就性能而言,我應該在本地維護實例變量i_attr *,還是應該使用類變量c_dict *通過字典查找來訪問它們?

如果這種恆定時間的微型優化很重要並且不成熟,可能不要使用python。

我強烈懷疑,這是不成熟的優化,並且您還沒有確定這是一個火鍋,因爲如果你有,你可能只是分析代碼兩種方式,而不會問在這裏。

您可以通過擔心你的架構得到更多的加速,你是否應該運行的長期的過程,可以充分利用的PyPI的等

0

您的問題在性能方面沒有一般答案,因爲它取決於訪問的頻率以及您如何使用結果,您只需嘗試一下即可。使用timeitprofile運行您的代碼以查看結果。

如果你想保持c_dictN同步與i_attrN,它可能是更好的使用類似:

self.i_attrN = property(lambda self:  MyClass.c_dictN[i_keyN], 
         lambda self, val: MyClass.c_dictN[i_keyN] = val) 

(注意,您也可以使用setattrgetattr來設置各個領域的循環,如果他們真的是像你的例子一樣命名)。

如果你能做到像上面,你可以改變你的類的合同,另一種解決方案是使用索引訪問,如:

def __getitem__(self, idx): 
    return MyClass.c_dict[idx][self.i_key[idx]] 

def __setitem__(self, idx, val): 
    MyClass.c_dict[idx][self.i_key[idx]] = val 

然後你可以改變從

訪問
a = myobj.i_attrN 
myobj.i_attrN = b 

a = myobj[N] 
myobj[N] = b 
+0

我應該補充說,所有的實例變量'i_attr *'在初始化時都會被設置一次(之後沒有改變),並且所有後續對它們的訪問都是內部的。這會有什麼不同嗎? – skyork

+0

然後我認爲你的差異是一個哈希查找與兩個。在任何情況下,影響都很小。 – Krumelur