2012-08-29 47 views
2

我正在使用哈希集結構進行映射:Dictionary<string, string>使用多次存儲O(1)hashet查找的結果是否是一種好習慣?

如果我需要在連續的語句中多次讀取myHashset [「key1」]的值,是否使用局部變量存儲第一個查找是一個好習慣?

編輯:沒有其他線程會修改字典,因此它不是一個重要的標準。

謝謝!

+2

是............. –

+0

當你知道結果不會改變時,反覆調用getter也是一樣。 – Thilo

+2

@Thilo:這不是真的可比。屬性獲取器比OP要求的要便宜和可讀。 –

回答

8

是的。

O(1)只是表明操作需要相同的時間量,不管有多少項。
這個不是的意思是,它所花費的時間與訪問局部變量一樣快。

此外,考慮以下因素:

  1. 訪問一個局部變量是更可讀
  2. 通常情況下,你想有錯誤處理或由它的鍵在字典中獲取的值時,甚至使用TryGetValue。使用局部變量時,可以將此代碼保留在一個地方,而不必在整個方法中塗抹它。
4

是:

  • 它避免了多個O(1)查找其耗時
  • ,它更不是每次
1

dictionary["key"]它是一個很好的做法更具可讀性至少有兩個原因:

  • 字典不是真正的O(1)。數據在內部被劃分爲小集合,Dictionary由於哈希碼而知道要搜索哪個集合。仍然有一個內部收集枚舉涉及,因此操作不是免費的(雖然不昂貴)

  • 該值可能會從另一個線程修改。保持引用有助於使代碼線程安全並防止意外結果。

+0

爲什麼不是O(1)?當你增加這些集合的數量時,時間不會增加。 – Thilo

+2

如果存在大量的散列衝突,字典只會劣化爲比O(1)更差。否則,Dictionary類真的是O(1)。 – GaussZ

+0

msdn文檔說「接近O(1)」和「檢索取決於哈希算法的質量」 – Magnus

0

是的...

你自己有答案。這將有助於節省微秒和CPU週期。 :)

1

做O(1)操作n次是O(n)!

這是一個小的優化,但並不是每一個小的優化都是一個早熟的問題。這確實會節省時間。

編輯:沒有其他線程會修改字典,所以它不是一個重要的標準。

沒有在手的情況下也許,但對什麼是好的做法而言,我們要考慮的更廣泛的情況下,不僅僅是一個在手 - 對什麼東西是部分「良好做法」是,它涵蓋了只有當我們知道我們爲什麼這樣做時,我們纔會離開大量具有類似代碼的案例。

不必穿線,我們的理由是:

  1. 我們反覆打相同的代碼具有相同的結果。
  2. 編譯器不可能意識到這一點,併爲我們重寫一次調用。
  3. 它可以提高可讀性。

最後一點值得考慮。每個變量的命名都是一個使代碼自動記錄的機會。這是更清晰的正在發生的事情:

CheckUpdated(dict[passedValue.split('\t')[1].Trim().ToUpperInvariant()]); 
MarkLastCheckTime(dict[passedValue.split('\t')[1].Trim().ToUpperInvariant()]); 
return GetStatus(dict[passedValue.split('\t')[1].Trim().ToUpperInvariant()]; 

或者:

var purchaseOrderCode = dict[passedValue.split('\t')[1].Trim().ToUpperInvariant()]; 
CheckUpdated(purchaseOrderCode); 
MarkLastCheckTime(purchaseOrderCode); 
return GetStatus(purchaseOrderCode); 

我是在第一種情況下有點故意神祕,我真的應該已經做了一些工作,只有一次即使我繼續使用相同的字典,但實際代碼中的較小效果更大,因爲它是一個充滿真實代碼的源文件,而不是四行代碼。

螺紋加工,就成了一個問題:

  1. 如果我們需要與可能的變化交錯,我們無法做到這一點。
  2. 否則,它消除了來自線程的很多風險,因爲我們在本地工作,並且知道它將始終在本地。

因此,雖然一些線程案例可以緩解這種方法,並且非常多地堅持它,並且它不再是優化,而是正確性的關鍵。

知道我們處於哪種情況並考慮其他線程會變得更加複雜 - 因爲有些情況下,如果另一個線程更新字典,我們確實希望允許有問題的對象發生變化。但大多數情況下,我們確實希望確保在面對來自其他線程的更改時繼續處理同一個對象。

所以,雖然在這裏並不重要,但它仍然是一般良好實踐的理由。

相關問題