2011-12-21 36 views
2

我的應用程序處理包含許多屬性的對象,其中一些屬性較輕,另一些屬性較重(需要計算,db查詢)。 在一些上下文中,我需要訪問所有的屬性,並且在其他上下文中(比如gridviews,或者當對象被用作另一個對象的成員時),我只需要訪問一些屬性。優化具有可變需要屬性的對象

我已經儘可能延遲了重載成員的加載,但是我不知道如何繼續避免「攜帶」我不需要的屬性。

我被告知要爲每個課程創建一個額外的'輕'版本來回應這個問題,但是我的應用程序包含50多個課程,因此需要花費很多時間來完成。此外,同一類的多個版本也會產生其他問題。

哪個解決方案更優化?創建多個類版本有意義嗎? 如果不需要的屬性保持爲空,該怎麼辦?與沒有這些屬性的同樣重的空(未分配)屬性的對象?

非常感謝您的回答!

+0

也許使用組合對象,即有另一個類與你的重要屬性,並有你的原始使用。儘管如此,這將是一個相當大的變化。 – 2011-12-21 10:39:46

+0

你擔心什麼成本?加載東西很昂貴,但是「攜帶」它的成本幾乎沒有。 – 2011-12-21 10:49:39

+0

@HenkHolterman我很擔心(其中包括)我只使用的對象集合可以說30個屬性中的5個。如果集合包含50個對象,則會產生50 * 25個不必要的屬性。如果這幾乎沒有成本,那確實不是問題。 – 2011-12-21 11:48:26

回答

0

也許你可以創建counstructor來僅初始化light屬性。並且對重度屬性進行延遲初始化(僅在訪問時進行初始化)。那麼你可以擁有一個重量輕的物體,這個物體當然具有所有的屬性,但是沒有初始化。

1

我不確定它會幫助你明確地解決你的問題,但是.NET 4.0引入了Lazy類,它是一個用於延遲初始化重/大對象實例的包裝類。它提供了一個.Value屬性,當它第一次被訪問時(並且只是第一次)初始化包裝的對象實例。如果.Value永遠不會被訪問,那麼被封裝的對象實例永遠不會被初始化。但聽起來你已經在自己做這個了,很可能在你的屬性Get/Set定義中。

在哪些對象比較重的方面,沒有屬性的輕量級類或帶有NULL變量的原始類:如果問題中的屬性是引用類型,那麼唯一的浪費是指向引用類型的指針, x86的每個屬性4個字節,x64的每個屬性8個字節。 .NET中空類實例的默認最小大小似乎約爲24個字節。

例如:

public class MyClassLight 
{ 
    public int PropertyInt { get; set; } // 4 byte value type 
    public OtherClass1 PropertyOtherClass1 { get; set; } // 4 or 8 byte reference type 
} 

public class MyClassHeavy 
{ 
    public int PropertyInt { get; set; } // 4 byte value type 
    public string PropertyString { get; set; } // 4 or 8 byte reference type 
    public OtherClass1 PropertyOtherClass1 { get; set; } // 4 or 8 byte reference type 
    public OtherClass2 PropertyOtherClass2 { get; set; } // 4 or 8 byte reference type 
} 

比方說,你在x86上運行的MyClassLight的實例將花費24個字節的開銷+ 4個字節+ 4個字節= 32個字節的內存。

MyClassHeavy將24字節開銷+ 4字節+4字節+4字節+4字節= 40字節的內存。

即使您的沉重類有50個屬性是引用類型,保持它們爲NULL每個實例只會產生額外的200字節內存(因爲類仍然需要爲指針保留內存,這可能用於一點)。如果在內存中有成千上萬或數百萬個這樣的對象,每個對象可能需要200字節,但如果不是這樣,它似乎可以忽略不計。

有50個類的2個版本增加的複雜性似乎不值得。但是如果你必須走這條路線,我會重構它來創建一個只包含兩個類(輕量級和重量級)共享的屬性的接口,然後重構代碼以儘可能地使用接口而不是具體類,因此它是兼容的與輕和重型班。