[英]Is there a more efficient way of creating a list based on an existing list and a lookup list?
我有以下方法,该方法需要很长时间才能运行,并且希望获得一些帮助,以使其运行更快或更高效。
该方法的主要职责是获取从CSV文件创建的数据点列表,通过DataLoggerTagname
属性将文件数据点的Name
属性映射到标记名列表中的HistorianTagname
属性,并从映射。 如果映射不存在,则忽略文件数据点。
我知道这是一个漫长的过程,但我希望这是有道理的。 只看一下方法可能会更容易:
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;
}
}
}
注意:我对类和映射方法有完全的控制权,所以如果我做的是根本错误的事情。 我会很高兴知道!
谢谢!
我将从修复开始:
var historianTagname = historianTagnames.FirstOrDefault(x => x.DataLoggerTagname.Equals(fileDatapoint.Name, StringComparison.OrdinalIgnoreCase))
要在此循环中运行每个迭代,这是一个非常昂贵的操作。
就像@Sheldon Warkentin所说的FirstOrDefault
可能是函数的瓶颈,最好创建一个以Name为键的Dictionary
historianTagnames Dictionary
,然后在函数中可以通过键获取值。
像下面这样:
// this is passed to method
IDictionary<string, Tagname> historianTagnames;
// .. method body
var historianTagname = historianTagnames[fileDatapoint.Name];
当然,您需要添加适当的if。
以下是我的主张:
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;
}
}
}
正如其他人所说, 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()) {
// ...
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.