2013-04-14 132 views
-1

如果對象是不可變的(我自己實現的目標)我應該使用屬性長度或只是只讀變量?如果對象具有Length作爲屬性,則在for循環中會失去一些性能。長度屬性

for (int i = 0; i < myObject.Length; i++) // Length is readonly variable 
{ 
    // some code 
} 

和:

int len = myObject.Length; // Length is a property 

for (int i = 0; i < len; i++) 
{ 
    // some code 
} 

你有什麼建議?

+1

您是否測量過該屬性會導致性能下降? 'get'ters通常很簡單,可以被JIT編譯器內聯,所以在字段和屬性之間不會有性能差異。 – dtb

+0

作業:使用字節*擦除內存for循環。使用來自object = X ms的變量。使用property = 2 * X ms。所以財產很慢。當我將Length複製到局部變量(來自對象變量)時,它會給出另一個10%的速度。所以最後我使用了Length屬性,然後在每個for循環之前將它的值複製到局部變量。當然,當我使用long *來清除內存時,將Length更改爲局部變量會更有用。所以我解決了它。 – zgnilec

回答

0

更改臨時變量來查詢是一個非常標準的重構。換句話說,強烈建議如果屬性調用非常快,那麼您不應該創建一個臨時變量。它被稱爲'replaceTempWithQuery'。下面是它的Blurb:

http://www.refactoring.com/catalog/replaceTempWithQuery.html

我強烈推薦這本書重構給大家,做節目。

添加爲一個編輯︰我得到了這個downvoted,但過早的優化是真的要避免 - 我只會建議修復一個查詢與溫度,如果它產生非常明顯的問題。

A famous quote from Donald Knuth: "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil"。無論如何,這是一個選擇的問題,除非你有很多代碼維護者。然後,維護時間通常會對您的優化/設計選擇產生重大影響。

1

除非你在這裏有一些非常大的特殊數據集,所以你期望做大量的循環迭代,屬性和變量之間的差異可能可以忽略不計。

簡單的選擇是去同一個變量。使用一個屬性會給你更多的好處,可以在不改變你的類的簽名的情況下修改它的行爲(例如,如果你想以某種新的方式計算長度)。

另一個相關的好處是可以私下設置屬性(如果需要,稍後更改),但只能公開閱讀。

我想我會去這些原因的屬性。無論如何,我不會僅僅根據對性能的預期影響做出這種選擇。

3

沒有辦法,它像一個樣品中很重要。 JIT沒有進入簡單​​的get的可能性非常低。即使get沒有內聯,多餘的函數調用不會是非常簡單的代碼之外的性能瓶頸。

爲了顯示我的意思,我在發佈模式下運行以下代碼(如果將其保留爲調試狀態,它將以不同的方式工作)。

private int Length { get; set; } 
private int _length; 
void Run() 
{ 
    Length = int.MaxValue; 
    _length = int.MaxValue; 
    var watch = new Stopwatch(); 
    watch.Start(); 
    for (int i = 0; i < Length; i++) 
    { 
    } 
    watch.Stop(); 
    Console.WriteLine("Elapsed: {0}ms", watch.ElapsedMilliseconds); 
    watch.Restart(); 
    for (int i = 0; i < _length; i++) 
    { 
    } 
    watch.Stop(); 
    Console.WriteLine("Elapsed: {0}ms", watch.ElapsedMilliseconds); 
} 

我跑了10次,得到了以下的平均值:743毫秒爲屬性,740毫秒爲變量。這種差異可能僅僅是因爲我的機器上發生的嘗試和其他事情數量較少。

現在,如果通過屬性關閉內聯,您將獲得時間差異:屬性爲4577毫秒,變量爲775毫秒。現在這聽起來像是一個巨大的差異(總共6倍的時間),但請記住我的循環條件:20億次迭代。這意味着差異大約是每次操作2 ns。換言之,大約有4個時鐘週期,除了最極端的性能情況外,還不足以擔心。