2012-05-04 76 views
1

我有以下方法,需要很長時間才能運行,並且會喜歡一些幫助,以使其運行得更快或更高效。基於現有列表和查找列表創建列表是否更有效?

該方法的主要責任是採取從CSV文件創建的數據點的列表,由DataLoggerTagname屬性的文件數據點的到到HistorianTagname屬性Name屬性映射在標記名的列表,並創建一個結果列表來自映射。如果映射不存在,則文件數據點將被忽略。

我知道這是囉嗦,但我希望它是有道理的。這可能是更容易只是看方法:

private IEnumerable<DataPoint> GetHistorianDatapoints(IEnumerable<DataPoint> fileDatapoints, IEnumerable<Tagname> historianTagnames) 
    { 
     /** 
     ** REFACTOR THIS 
     **/ 

     foreach (var fileDatapoint in fileDatapoints) 
     { 
      var historianTagname = historianTagnames.FirstOrDefault(x => x.DataLoggerTagname.Equals(fileDatapoint.Name, StringComparison.OrdinalIgnoreCase)); 
      if (historianTagname != null) 
      { 
       var historianDatapoint = new DataPoint(); 

       historianDatapoint.Name = historianTagname.HistorianTagname; 
       historianDatapoint.Date = fileDatapoint.Date; 
       historianDatapoint.Value = fileDatapoint.Value; 

       yield return historianDatapoint; 
      } 
     } 
    } 

注: 我的類和映射的方法完全控制,所以,如果我做的東西基本上是錯誤的。我會很高興知道!

謝謝!

+1

如果存在大量標記名,則使用歷史標記名的冠詞。你基本上會一遍又一遍地查看它們,並且dictrionary會節省一些計算量 –

+3

你有沒有考慮將你的historianTagNames存儲到一個'Dictionary dic = new Dictionary (StringComparer.OrdinalIgnoreCase);'Then只需用'dic ['yourkey']訪問historianTagName''這應該會給你更好的表現,我相信? –

+1

@AdolfoPerez:將StringComparer作爲EqualityComparer傳遞給字典的+1好主意 – empi

回答

2

下面是我的命題:

private IEnumerable<DataPoint> GetHistorianDatapoints(IEnumerable<DataPoint> fileDatapoints, IEnumerable<Tagname> historianTagnames) 
{ 
    var tagNameDictionary = historianTagnames.ToDictionary(t => t.DataLoggerTagname, StringComparer.OrdinalIgnoreCase); 

    foreach (var fileDatapoint in fileDatapoints) 
    {     
     if (tagNameDictionary.ContainsKey(fileDatapoint.Name)) 
     { 
      var historianTagname = tagNameDictionary[fileDatapoint.Name]; 
      var historianDatapoint = new DataPoint(); 

      historianDatapoint.Name = historianTagname.HistorianTagname; 
      historianDatapoint.Date = fileDatapoint.Date; 
      historianDatapoint.Value = fileDatapoint.Value; 

      yield return historianDatapoint; 
     } 
    } 
} 
+0

我真的很喜歡Adolfo Perez的評論和更新代碼 - 我認爲它現在更清潔了。 – empi

+0

感謝您的完整代碼示例。使用字典,映射現在實際上是瞬時的。謝謝所有人的貢獻! – Khan

4

我會被固定起來開始:

var historianTagname = historianTagnames.FirstOrDefault(x => x.DataLoggerTagname.Equals(fileDatapoint.Name, StringComparison.OrdinalIgnoreCase)) 

這是一個非常昂貴的操作,通過這個循環運行每次迭代。

2

@Sheldon WarkentinFirstOrDefault可能是你的瓶功能的脖子,I S更能營造historianTagnames一個Dictionary者皆其中Name是關鍵,那麼在你的功能,你可以得到價值。

喜歡的東西波紋管:

// this is passed to method 
IDictionary<string, Tagname> historianTagnames; 
// .. method body 
var historianTagname = historianTagnames[fileDatapoint.Name]; 

ofcourse你需要的,如果對加適量。

0

正如其他人所說,一個Dictionary<string, Tagname>可能會表現得更好。

var historianDict = new Dictionary<string, Tagname>(); 
foreach (var tagName in historianTagnames) { 
    historianDict[tagName.DataLoggerTagname.ToLowerInvariant()] = tagName; 
} 

foreach (var fileDatapoint in fileDatapoints) { 
    if (historianDict.ContainsKey(fileDatapoint.Name.ToLowerInvariant()) { 
     // ... 
    } 
} 
相關問題