我需要重写代码以提高执行原始代码的速度:
数据类:
public class Data
{
public string Id {get;set;}
... Other properties
}
服务:(例如,有两个以上的jus给你2个)
public class SomeService1
{
public Result Process(Data data)
{
//Load data from different services hire
}
}
public class SomeService2
{
public Result Process(Data data)
{
//Load data from different services hire
}
}
实际方法
public void Calculate (List<Data> datas)
{
Result result;
SomeService1 someService1 = new SomeService1();
SomeService2 someService2 = new SomeService2();
// In this place list of data have about 2000 elements
foreach(var data in datas)
{
switch(data.Id)
{
case 1:
result = someService1.Process(data)
break;
case 2:
result = someService2.Process(data)
break;
default:
result = null;
}
ProcesAndSaveDataToDatabase(result);
}
}
方法Calculate
我将List作为此列表中每个元素的参数,它从外部服务中获取数据(服务由Data类中的id确定)。然后它处理这些数据并保存到数据库。对于2000个元素,整个操作大约需要8分钟。 70%的时间是从外部服务收集数据。我必须改变那个时间。我只有一个想法可以做到这一点,但说实话,我无法用数据进行测试,因为只有数据在生产环境上(生产测试是个坏主意)。我有一个想法。如果我朝着正确的方向前进,你能看到它并给我建议吗?
数据类:
public class Data
{
public string Id {get;set;}
... Other properties
}
服务:(例如,有两个以上的jus给你2个)
public class SomeService1 : IService
{
public Result Process(Data data)
{
//Load data from different services hire
}
}
public class SomeService2 : IService
{
public Result Process(Data data)
{
//Load data from different services hire
}
}
IService:
public interface IService
{
Result Process(Data data);
}
实际方法:
Public void Calculate (List<Data> datas)
{
var split= from data in datas group data by data.Id into newDatas select newDatas
// Different list split by Id
Parallel.Foreach(split, new ParallelOptions{MaxDegreeOfParallelism = 4}, datas =>
{
Result result;
IService service = GetService(datas.FirsOfDefault().Id);
if(service == null) return;
foreach(var data in datas)
{
result = service.Process(data)
ProcesAndSaveDataToDatabase(result);
}
});
}
private IService GetService(string id)
{
IService service = null;
if(id == null ) return service;
switch(id)
{
case 1:
service = new SomeService1();
break;
case 2:
service = new SomeService2();
break;
}
return service;
}
在这个想法中,我尝试将不同的服务数据拆分为不同的线程。所以在列表中我们将有20个项目Id = 1
和10个项目Id = 2
它应该创建2个独立的线程并离散处理它应该允许我切断执行时间。这是好方法吗?是否有其他可能性来改进此代码?
谢谢
答案 0 :(得分:3)
并行ForEach有助于改进CPU绑定任务,但您在上面提到的是并行调用IO绑定的服务。每当你进行IO绑定工作(比如调用外部服务)时,最好使用async并等待而不是并行foreach。
并行ForEach将启动多个线程并阻止这些线程直到工作完成(大约8分钟,所有线程都被阻止)。
Async和Await将在服务调用之间编织工作线程,并有效地使用IO完成端口回调到您的应用程序。这可以避免阻塞多个线程,并允许您更有效地使用计算机的资源。
有关如何在此处进行并行异步调用的更多信息:
答案 1 :(得分:2)
虽然您将在应用程序中获得使用Parallelism(Parallel.ForEach)的好处,但这并不是提高代码执行速度的唯一方法。
此外,由于您在应用程序中使用LINQ并且可能也在广泛使用它,因此您可能希望尽可能使用 PLINQ (并行LINQ)。
我还建议您尝试分析代码,以确定应用中的热点和瓶颈,这可能是让您更好地了解在何处以及如何改善绩效。
另外,正如Patrick所提到的,您应尽可能尝试使用 async 和等待。
从MSDN查看此文章,我们将为您提供更多见解https://msdn.microsoft.com/en-us/library/ff963552.aspx