我如何才能使这个函数更高效呢?它目前的运行时间为6 - 45秒。我已经在这个特定的方法上运行了dotTrace分析器,它的总时间在6,000ms到45,000ms之间。大部分时间都花在了"MoveNext"和"GetEnumerator"调用上。
例如
71.55% CreateTableFromReportDataColumns - 18, 533* ms - 190 calls
-- 55.71% MoveNext - 14,422ms - 10,775 calls
我能做些什么来加速这个方法吗?它被调用了很多次,并且秒数加起来:
private static DataTable CreateTableFromReportDataColumns(Report report)
{
DataTable table = new DataTable();
HashSet<String> colsToAdd = new HashSet<String> { "DataStream" };
foreach (ReportData reportData in report.ReportDatas)
{
IEnumerable<string> cols = reportData.ReportDataColumns.Where(c => !String.IsNullOrEmpty(c.Name)).Select(x => x.Name).Distinct();
foreach (var s in cols)
{
if (!String.IsNullOrEmpty(s))
colsToAdd.Add(s);
}
}
foreach (string col in colsToAdd)
{
table.Columns.Add(col);
}
return table;
}
如果需要sql表定义,请在此处输入:
- 报表数据**
ReportID int
- 报表数据列**
ReportDataColumnId int
ReportDataId int
Name varchar(255)
Value text
5条答案
按热度按时间cnjp1d6j1#
我相信你应该可以把你的函数简化成这样
然后将这些名字添加到您的表中。
t5zmwmid2#
您的代码(仅)运行foreach循环,因此得出该方法大部分时间都在MoveNext()等中的结论并不奇怪。
您正在isnullOrEmpty和Distinct(由HashSet重复)上执行双重操作。
我的版本是:
但我并不指望
voase2hg3#
您应该在提出问题时提到LinqToSql,这样您就会得到一些响应来查看您的数据库,看看它是长时间运行的查询还是重复的往返查询
另外,使用sql事件探查器捕获发出的查询。
最后,您可能需要一个或两个索引来降低IO。列顺序在这里很重要。
ryhaxcpt4#
这可能是Hank代码的一点改进,它利用了HashSet会告诉你Add操作是否成功或者元素是否已经存在的事实。
**编辑:**我在开始时将null和“”添加到散列集,因此我们不再需要检查null或empty。
jdgnovmf5#
这样做可能有些过头(取决于ReportDatas中的条目数、每个ReportDataColumns中的列数、主机上的内核数等),但您也可以进行并行化。
例如,如果您决定并行处理ReportDatas条目,您可以让每个条目创建自己的列集合,或者让它们全部写入ConcurrentBag,在完成所有操作后使用Distinct或执行其他操作。