【发布时间】:2019-02-24 20:46:04
【问题描述】:
我有一个数据拉取服务,我的 C# 应用程序通过该服务拉取数据。使用多个作业拉入数据,一旦数据请求完成,数据拉取服务将调用我在应用程序类中实现的notify 方法。
以下是notify方法代码。它只是检查结果是否为非空,然后在新线程中调用mergeResults。
public override void notify(List<IFields> results)
{
if (!results.IsNullOrEmpty())
{
Task.Run(() => { mergeResults(results); });
}
}
我正在使用列表来存储最终合并结果。
List<IFields> mergedResults;
我使用object mergeLock 进行互斥。
这是我正在使用的合并逻辑:
public void mergeResults(List<IFieldsByPrePost> results)
{
lock (mergeLock)
{
foreach (var result in results)
{
if (mergedResults.Count > 0)
{
var properties = mergedResults.First().getDiffProperties();
bool isMatch = false;
foreach (var mergedResult in mergedResults)
{
isMatch = true;
foreach (var property in properties)
{
var value1 = mergedResult.GetType().GetProperty(property).GetValue(mergedResult).ToString();
var value2 = result.GetType().GetProperty(property).GetValue(result).ToString();
if (value1 != value2) { isMatch = false; break; }
}
if (isMatch)
{
mergedResult.Count += result.Count;
break;
}
}
if (!isMatch)
{
mergedResults.Add(result);
}
}
else
{
mergedResults.Add(result);
}
}
}
}
上述逻辑可以工作,但是很慢,只要将大量结果传递给方法。
另外,notify 方法被数据拉取服务多次调用,结果集不同,进一步减慢了它的速度。
我正在寻找更好的方法来解决这个问题。
TLDR;这个算法很慢,谁能教我一个让它跑得更快的方法吗?
【问题讨论】:
-
如果您可以提供minimal reproducible example 并提供示例输入和基于这些示例输入的预期结果,那就太棒了。
-
首先,您需要使用断点查看哪一行速度较慢,然后重新创建该函数或使用其他函数。
-
如果您能比
very slow和large set of results更具体,那就太好了。 -
我很确定反射方法是导致性能问题的原因之一。为什么你需要它?长操作开头的
lock (mergeLock)会阻塞整个程序,所以Task.Run似乎没用 -
在你的
IFieldsByPrePost类中写一个类似IsMatch(IFieldsByPrePost post){...}的函数而不是getDiffProperties();是一种替代方法吗?