У меня есть код, который мне нужно переписать, чтобы улучшить скорость выполнения исходного кода:ли Parallel.ForEach это лучший способ улучшить скорость выполнения этого кода
класса данных:
public class Data
{
public string Id {get;set;}
... Other properties
}
Услуги: (Есть более чем 2 я 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 как параметр для каждого элемента в этом списке, он захватывает данные из внешней службы (услуга определяется по идентификатору в классе данных). Затем он обрабатывает эти данные и сохраняет их в базе данных. Для 2000 элементов целая операция занимает около 8 мин. 70% времени собирает данные из внешней службы. Я должен изменить это время. У меня есть только одна идея сделать это, но, честно говоря, я не могу протестировать ее с данными, потому что только данные относятся к производственной среде (а тестирование на производстве - плохая идея). У меня есть одна идея. Можете ли вы посмотреть на это и посоветуете мне, если я пойду в правильном направлении?
класс данных:
public class Data
{
public string Id {get;set;}
... Other properties
}
Услуги: (Есть более чем 2 I Jus дают U 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 разделенных потока и обработать их дискретно, это должно позволить мне отключить время выполнения. Это хороший способ? Есть ли другие возможности для улучшения этого кода?
Благодаря
Если 70% времени тратится вытягивать данные из службы, которые были бы то, что вам нужно оптимизировать. У вас есть контроль над сервисом? – SledgeHammer
Нет. Там за пределами службы, и у меня есть только служебная ссылка на нее – Aht
, поэтому требуется ~ 5.6 минут, чтобы вытащить данные поочередно сейчас? Если вы сделаете эту часть параллельной, она будет быстрее, так как вы нажимаете на эту услугу несколько раз подряд. Кроме того, используйте профилировщик в своем локальном коде, чтобы узнать, что вы можете оптимизировать на своей стороне ... но вы никогда не будете быстрее, чем услуга может доставить. – SledgeHammer