Skip to content

Commit 49d00af

Browse files
authored
Merge pull request #141 from tarekgh/PerfEnhancement
Tracking Perf enhancement in multi-threading scenario
2 parents 9150603 + 39c1d1d commit 49d00af

File tree

3 files changed

+47
-13
lines changed

3 files changed

+47
-13
lines changed

src/coverlet.core/Coverage.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,15 @@ private void CalculateCoverage()
183183
{
184184
int ordinal = int.Parse(info[3]);
185185
var branch = document.Branches[(start, ordinal)];
186-
branch.Hits = hits;
186+
branch.Hits += hits;
187187
}
188188
else
189189
{
190190
int end = int.Parse(info[3]);
191191
for (int j = start; j <= end; j++)
192192
{
193193
var line = document.Lines[j];
194-
line.Hits = hits;
194+
line.Hits += hits;
195195
}
196196
}
197197
}

src/coverlet.tracker/CoverageTracker.cs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,39 @@ namespace Coverlet.Tracker
77
{
88
public static class CoverageTracker
99
{
10-
private static Dictionary<string, Dictionary<string, int>> _events;
10+
private static List<Dictionary<string, Dictionary<string, int>>> _events;
11+
12+
[ThreadStatic]
13+
private static Dictionary<string, Dictionary<string, int>> t_events;
1114

1215
[ExcludeFromCodeCoverage]
1316
static CoverageTracker()
1417
{
15-
_events = new Dictionary<string, Dictionary<string, int>>();
18+
_events = new List<Dictionary<string, Dictionary<string, int>>>();
1619
AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);
1720
AppDomain.CurrentDomain.DomainUnload += new EventHandler(CurrentDomain_ProcessExit);
1821
}
1922

2023
[ExcludeFromCodeCoverage]
2124
public static void MarkExecuted(string file, string evt)
2225
{
23-
lock (_events)
26+
if (t_events == null)
27+
{
28+
t_events = new Dictionary<string, Dictionary<string, int>>();
29+
lock (_events)
30+
{
31+
_events.Add(t_events);
32+
}
33+
}
34+
35+
// We are taking the lock only for synchronizing with CurrentDomain_ProcessExit event
36+
// but the lock should be fast as the thread shouldn't block before getting process exit event
37+
lock (t_events)
2438
{
25-
if (!_events.TryGetValue(file, out var fileEvents))
39+
if (!t_events.TryGetValue(file, out var fileEvents))
2640
{
2741
fileEvents = new Dictionary<string, int>();
28-
_events.Add(file, fileEvents);
42+
t_events.Add(file, fileEvents);
2943
}
3044

3145
if (!fileEvents.TryGetValue(evt, out var count))
@@ -42,16 +56,30 @@ public static void MarkExecuted(string file, string evt)
4256
[ExcludeFromCodeCoverage]
4357
public static void CurrentDomain_ProcessExit(object sender, EventArgs e)
4458
{
59+
Dictionary<string, bool> encounteredFile = new Dictionary<string, bool>();
60+
4561
lock (_events)
4662
{
47-
foreach (var files in _events)
63+
foreach (var localEvents in _events)
4864
{
49-
using (var fs = new FileStream(files.Key, FileMode.Create))
50-
using (var sw = new StreamWriter(fs))
65+
lock (localEvents)
5166
{
52-
foreach (var evt in files.Value)
67+
foreach (var files in localEvents)
5368
{
54-
sw.WriteLine($"{evt.Key},{evt.Value}");
69+
FileMode mode = FileMode.Append;
70+
if (!encounteredFile.TryGetValue(files.Key, out bool b))
71+
{
72+
encounteredFile.Add(files.Key, true);
73+
mode = FileMode.Create;
74+
}
75+
using (var fs = new FileStream(files.Key, mode))
76+
using (var sw = new StreamWriter(fs))
77+
{
78+
foreach (var evt in files.Value)
79+
{
80+
sw.WriteLine($"{evt.Key},{evt.Value}");
81+
}
82+
}
5583
}
5684
}
5785
}

test/coverlet.core.performancetest/PerformanceTest.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using coverlet.testsubject;
2+
using System.Threading.Tasks;
3+
using System.Collections.Generic;
24
using Xunit;
35

46
namespace coverlet.core.performancetest
@@ -18,10 +20,14 @@ public void TestPerformance(int iterations)
1820
{
1921
var big = new BigClass();
2022

23+
List<Task> tasks = new List<Task>();
24+
2125
for (var i = 0; i < iterations; i++)
2226
{
23-
big.Do(i);
27+
tasks.Add(Task.Run(() => big.Do(i)));
2428
}
29+
30+
Task.WaitAll(tasks.ToArray());
2531
}
2632
}
2733
}

0 commit comments

Comments
 (0)