【发布时间】:2016-08-19 04:15:23
【问题描述】:
我有代码需要重写以提高执行原始代码的速度:
数据类:
public class Data
{
public string Id {get;set;}
... Other properties
}
服务:(例如我给你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 作为该列表中每个元素的参数,它从外部服务获取数据(服务由数据类中的 id 确定)。然后它处理这些数据并保存到数据库。对于 2000 个元素,整个操作大约需要 8 分钟。 70% 的时间是从外部服务收集数据。我必须改变那个时间。我只有一个想法可以做到这一点,但老实说,我无法用数据对其进行测试,因为只有数据在生产环境中(并且在生产环境中进行测试是个坏主意)。我有一个想法。如果我朝着正确的方向前进,你能看看它并给我建议吗?
数据类:
public class Data
{
public string Id {get;set;}
... Other properties
}
服务:(例如我给你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
}
}
服务:
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 个分离的线程并离散地处理它,这应该可以让我切断执行时间。这是好方法吗?是否还有其他改进此代码的可能性?
谢谢
【问题讨论】:
-
如果 70% 的时间都花在从服务中提取数据上,那么这就是您需要优化的地方。您对服务有任何控制权吗?
-
不。有外部服务,我只有服务参考
-
所以现在串行提取数据需要大约 5.6 分钟?如果您使该部分并行,它将更快,因为您一次多次访问该服务。此外,在您的本地代码上使用分析器来查看您可以优化什么……但您永远不会比服务可以提供的更快。
标签: c# multithreading optimization