В настоящее время я изучаю некоторые серьезные падения производительности в приложении.
Падения производительности странного рода - несколько итераций подряд работают довольно быстро, но есть одна итерация, которая требует гораздо больше времени дляполный.Это приложение работает с графикой, поэтому выглядит очень раздражающим.
Пожалуйста, взгляните на следующий код.
while (true)
{
var rng = new Random(1);
var concurrenBag = new ConcurrentBag<ICollection<(int X, int Y)>>();
Parallel.For(0, 20000, i =>
{
var entry = new List<(int X, int Y)>(); // essentially, this is what's going on:
var r = rng.Next(0, 3); // around 20k handlers return coordinates of pixels to redraw
for (var j = 0; j < r; j++) // sometimes there are null entries, sometimes 1, more often 2
{ // all entries are added to concurrent bag
entry.Add((j, j * j));
}
if (entry.Count == 0)
entry = null;
concurrenBag.Add(entry);
});
var sw = Stopwatch.StartNew();
var results = concurrenBag.ToList().AsParallel().Where(x => x != null).SelectMany(x => x).Distinct().ToList(); // this is where severe performance drops occur from time to time
var time = sw.ElapsedMilliseconds;
Console.WriteLine($"CB count: {concurrenBag.Count:00000}, result count: {results.Count:00}, time: {time:000}");
//Thread.Sleep(1000);
}
Этот код дает следующие результаты:
CB count: 20000, result count: 02, time: 032 <- this is fine, initialization and stuff
CB count: 20000, result count: 02, time: 004
CB count: 20000, result count: 02, time: 014 <- this is not fine
CB count: 20000, result count: 02, time: 003
CB count: 20000, result count: 02, time: 004
CB count: 20000, result count: 02, time: 004
CB count: 20000, result count: 02, time: 003
CB count: 20000, result count: 02, time: 015 <- every couple of frames it happens again
CB count: 20000, result count: 02, time: 003
CB count: 20000, result count: 02, time: 019
CB count: 20000, result count: 02, time: 004
CB count: 20000, result count: 02, time: 004
CB count: 20000, result count: 02, time: 003
CB count: 20000, result count: 02, time: 014
CB count: 20000, result count: 02, time: 003
CB count: 20000, result count: 02, time: 004
CB count: 20000, result count: 02, time: 003
CB count: 20000, result count: 02, time: 008
CB count: 20000, result count: 02, time: 003
CB count: 20000, result count: 02, time: 004
CB count: 20000, result count: 02, time: 011
CB count: 20000, result count: 02, time: 003
CB count: 20000, result count: 02, time: 003
CB count: 20000, result count: 02, time: 004
Я полагаю, у вас есть идея.В реальном приложении каждая «хорошая» итерация занимает около 10–15 мс, и эти медленные итерации происходят каждые 6–8 итераций и занимают до 150 мс или что-то в этом роде.
Я, честно говоря, думал, что что-то не так с моимбизнес-логика, но вы можете запустить приведенный выше пример и получить совершенно такие же результаты.Теперь я предполагаю, что что-то не так с тем, как я использовал Parallel.For
, AsParallel()
или ConcurrentBag
, но я понятия не имею, что именно не так.