2012-08-29 33 views
1

我有一個高級程序,它從數據庫中檢索數據,並通過C#中的ExpandoObjects從數據創建對象。優化字典在C#中添加ExpandoObjects

我現在正在優化我的整個過程,但遇到了一段代碼,這是性能方面的瓶頸。我很好奇我到底能furhter優化這段代碼,並已經成功地以最快的速度通過執行以下操作運行3次:在一個單獨的

  • 分隔「的發現‘類型’一節」循環並且只在它尚未初始化時才迭代它。
  • 添加了一個案例,當值爲null並且創建一個空字符串時,由於某些原因,Dictionary.Add在添加Null值時變慢了很多。

    // Holds all objects that are created inside the object. 
        Dictionary<string, IDictionary<string, dynamic>> objects = new Dictionary<string, IDictionary<string, dynamic>>(); 
    
        // This foreach loop is the slowest part! 
        foreach (KeyValuePair<string, dynamic> pair in fields) 
        { 
         string type = pair.Key.Split('_')[0]; 
    
         IDictionary<string, dynamic> obj; 
         if (!objects.TryGetValue(type, out obj)) 
         { 
          obj = new ExpandoObject(); 
          objects.Add(type, obj); 
         } 
         int location = pair.Key.IndexOf(type + "_"); 
         string key = pair.Key.Remove(location, type.Length + 1); 
         if (pair.Value == null)   // If Value is null, replace it with an empty string (dictionary slows quite alot when passing it null values) 
          obj.Add(key, ""); 
         else 
          obj.Add(key, pair.Value);   
        } 
    
        if (types == null) 
         types = objects.Select(x => x.Key).ToList(); 
    

我想知道,它是如何將Null值時詞典減慢這麼多,難道是在底層結構就遇到空值時做特殊操作?還有什麼我失蹤,進一步優化代碼?

任何幫助,再次非常感謝。


UPDATE

  • 編輯的代碼與最近的更改我已經從SO聚集。
+0

請注意,您的編輯沒有得到我提出的所有更改。你錯過了循環結尾的重要部分:'obj.Add'而不是'objects [type] .Add' –

+0

@DanielHilgarth,你是對的!我一定錯過了,對不起:)。我再次編輯了這篇文章。 –

回答

2

您可以通過使用TryGetValue代替ContainsKey避免在字典中的多次查找:

foreach (KeyValuePair<string, dynamic> pair in fields) 
{ 
    string type = pair.Key.Split('_')[0]; 

    IDictionary<string, dynamic> obj; 
    if (!objects.TryGetValue(type, out obj)) 
    { 
     obj = new ExpandoObject(); 
     objects.Add(type, obj); 
    } 
    int location = pair.Key.IndexOf(type + "_"); 
    string key = pair.Key.Remove(location, type.Length + 1); 
    if (pair.Value == null) 
     obj.Add(key, ""); 
    else 
     obj.Add(key, pair.Value);    
} 

BTW:你在第二foreach循環使用types我沒有看到。因此,你可以用這個簡單的代碼替換第一foreach循環:

types = objects.Select(x => x.Key).ToList(); 

這應該節省相當多的時間,因爲它消除在types列表中的慢搜索和類型的雙解析。

顯然這需要放在我上面顯示的foreach循環之後。

+0

當然!忘記了使用字典。謝謝! –

+0

@JoeyDewd:請參閱更新。 –

+0

謝謝。速度沒有太大提高,但確實清理了代碼! :) –