2014-05-07 61 views
-1

我有一個標誌字典和每個事件,我設置相關的標誌。有些事件來自同一類型,並且具有相同的ID,因此可以多次設置它們的標誌。如果在設置之前檢查一個標誌,它會更快嗎?性能比較:檢查並設置一個標誌VS.只需設置標誌

Dictionary<int, bool> flags = new Dictionary<string, bool>(); 
foreach(var eventType in eventTypes) 
{ 
    flags.Add(eventType.id, false); 
} 
for (int i = 0; i < iterations; i++) 
{ 
    // resetting flags for current iteration. 
    foreach(var k in flags.Keys) 
    { 
     flags[k] = false; 
    } 
    Event[] events = GetEvents(); 
    foreach(var e in events) 
    { 
     flags[e.id] = True; // Would it be better to check flag before set it? 
    } 
    // Do related works for events occurred 
} 
+0

爲什麼/爲了什麼你想檢查標誌? – ChrFin

+0

@chrfin避免設置之前的標誌。活動可以有相同的ID。 – Mehraban

+0

你的意思是如果它不是'假',那麼只設置它爲'false'? – ChrFin

回答

2

這種情況下最昂貴的操作發生在索引字典時。無論何時您嘗試添加,更新或讀取特定鍵的值,Dictionary都需要計算您的鍵的哈希值,然後獲取相應的桶,然後遍歷該桶中的元素(如果有多個散列衝突)並將它們與密鑰進行比較。

如果您在更新之前檢查了值,則需要執行兩次,以防需要更改值。

在附註中,這正是爲什麼TryGetValue是獲取可能在字典中或可能不在字典中的值的首選(更高性能)方法:因爲調用ContainsKey然後索引字典需要兩個操作(或,更糟的是,趕上KeyNotFoundException)。

另外,如果您的int鍵的範圍有限,則可以考慮使用BitArray而不是Dictionary

[編輯]

據推測,您使用字典來檢查,如果給定的事件至少發生了一次。要做到這一點,你可以簡單的寫:

var eventIds = new HashSet<string>(GetEvents().Select(e => e.Id)); 

要檢查是否有效發生的事件,您將查詢的HashSet:

if (eventIds.Contains(id)) 
{ 
    // do something 
} 
1

只設置標誌,以false如果他們true是比較慢的,因爲你需要查詢字典的兩倍。
如果您直接設置標誌,它只有一個操作。

另外,如果你有一個多線程環境,你還需要防止競爭條件。將lock圍繞「檢查&設置」邏輯,這會使其變慢。

做一個我能想到的檢查的唯一原因是,如果你有一個自定義字典,它會觸發set事件上的某些事件,即使它是相同的值,並且你想避免這種情況。

2

在任何基於字典的操作,查詢的時間很可能會遠遠超過設置標誌所需的時間,通常只需要在內存中設置一個值。

如果您只是設置標誌而不檢查,那麼只涉及一次查找。

如果您先檢查,那麼這可能涉及兩個查找。不過,編譯器很可能會將其優化爲僅查找一次,因此速度可能相似。

結論:

  • 不檢查是可能更快,但這隻會是明顯的,如果如果你真的關心性能的編譯器是不擅長optimzation

  • ,考慮是否您可以在應用程序中使用數組而不是字典,因爲數組往往會更快。

但是,這只是基於我的知識和本能。如果你對性能非常認真,那麼唯一真正的解決方案是編寫一些代碼來測試各種方法的速度!