Я попробовал несколько предложений, и это пока самый быстрый способ получить:
private static void TestForPreCountingParallel(List<TraiderItem> traiderItems, List<BaseItem> baseItems)
{
var watch = new Stopwatch();
watch.Start();
ConcurrentBag<TraiderItem> traiderItemsInBase = null;
for (int i = 0; i < 3; i++)
{
traiderItemsInBase = new ConcurrentBag<TraiderItem>();
var baseFeesRounds = baseItems.Select(bi => Math.Round((double)bi.Fee * 0.4, 8)).ToArray();
Parallel.ForEach(traiderItems, traiderItem =>
{
double traiderFeeRound = Math.Round(traiderItem.Fee, 8);
for (var index = 0; index < baseItems.Count; index++)
{
var baseItem = baseItems[index];
if (traiderItem.DateUtc == baseItem.DateUtc && traiderFeeRound == baseFeesRounds[index])
{
traiderItemsInBase.Add(traiderItem);
break;
}
}
});
Console.WriteLine(i + "," + watch.ElapsedMilliseconds);
}
watch.Stop();
Console.WriteLine("base:{0},traid:{1},res:{2},time:{3}", baseItems.Count, traiderItems.Count,
traiderItemsInBase.Count, watch.ElapsedMilliseconds);
}
У кого-нибудь есть еще улучшения?
Для вещей, которые я пробовал, это так:
- Оригинал Linq: база: 100000, трейд: 20000, разрешение: 40, время: 102544
- Преобразовано в циклы foreach:
Основание: 100000, Traid: 20000, разрешение: 40, время: 43890
- Плата за предварительный сбор: база: 100000, трейд: 20000, разрешение: 40, время: 22661
- Параллельный внешний цикл: основание: 100000, трейд: 20000, разрешение: 40, время: 6823
Времена незначительны, тенденция на что смотреть. Тест не идеален, я мало играл с соотношением TraiderItems внутри BaseItems, мой собственный, как видите, довольно низкий. 40 из 100000.
Итак, просто чтобы увидеть несколько различных соотношений:
- база: 100000, Traid: 20000, разрешение: 400, время: 50842
- база: 100000, Traid: 20000, разрешение: 400, время: 21754
И еще:
- база: 100000, Traid: 20000, разрешение: 2000, время: 118150
- база: 100000, Traid: 20000, разрешение: 2000, время: 57832
- база: 100000, Traid: 20000, разрешение: 2000, время: 21659
- база: 100000, Traid: 20000, разрешение: 2000, время: 7350
Я не эксперт, поэтому я должен ссылаться на другие источники, такие как:
http://mattwarren.org/2016/09/29/Optimising-LINQ/
В чем проблема с LINQ?
Как обрисовал в общих чертах Джо Даффи, LINQ вводит неэффективность в форме
скрытых отчислений
Итак, вывод такой:
- сделайте свой собственный тест и сначала попробуйте внести некоторые изменения в код, если вы действительно
заботиться о производительности. Просто добавление грубой силы к неэффективному
код будет стоить кому-то денег.
- не используйте сложные запросы LINQ для большой коллекции, пока вы не протестируете
производительность. Я сгорел от этого, порог
на удивление мало (например, 10 тыс. предметов с неправильным LINQ может убить
время обработки, когда простой цикл работает хорошо).
Но мне очень нравится LINQ и я часто его использую.