Skip to content

Commit 7838be3

Browse files
committed
Performance improvement for history parser
1 parent fabbe42 commit 7838be3

File tree

1 file changed

+37
-35
lines changed

1 file changed

+37
-35
lines changed

src/ReportGenerator.Core/Reporting/History/HistoryParser.cs

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Concurrent;
23
using System.Collections.Generic;
34
using System.Globalization;
45
using System.Linq;
@@ -54,7 +55,7 @@ internal HistoryParser(IHistoryStorage historyStorage, int maximumNumberOfHistor
5455
/// </summary>
5556
/// <param name="assemblies">The assemblies.</param>
5657
/// <param name="overallHistoricCoverages">A list to which all history elements are added.</param>
57-
internal void ApplyHistoricCoverage(IEnumerable<Assembly> assemblies, IList<HistoricCoverage> overallHistoricCoverages)
58+
internal void ApplyHistoricCoverage(IEnumerable<Assembly> assemblies, List<HistoricCoverage> overallHistoricCoverages)
5859
{
5960
if (assemblies == null)
6061
{
@@ -84,7 +85,7 @@ internal void ApplyHistoricCoverage(IEnumerable<Assembly> assemblies, IList<Hist
8485
Logger.ErrorFormat(" " + Resources.ErrorDuringReadingHistoricReports, ex.GetExceptionMessageForDisplay());
8586
return;
8687
}
87-
88+
var classes = assemblies.SelectMany(t => t.Classes).ToDictionary(k => this.GetFullClassName(k.Assembly.Name, k.Name), v => v);
8889
Parallel.ForEach(
8990
files,
9091
new ParallelOptions {MaxDegreeOfParallelism = this.numberOfReportsParsedInParallel},
@@ -98,40 +99,10 @@ internal void ApplyHistoricCoverage(IEnumerable<Assembly> assemblies, IList<Hist
9899
DateTime date = DateTime.ParseExact(document.Root.Attribute("date").Value, "yyyy-MM-dd_HH-mm-ss", CultureInfo.InvariantCulture);
99100
string tag = document.Root.Attribute("tag")?.Value;
100101
tag = string.IsNullOrEmpty(tag) ? null : tag;
101-
102-
foreach (var assemblyElement in document.Root.Elements("assembly"))
102+
var historicCoverages = this.ParseHistoricFile(classes, document, date, tag);
103+
lock (locker)
103104
{
104-
Assembly assembly = assemblies.SingleOrDefault(a => a.Name == assemblyElement.Attribute("name").Value);
105-
106-
foreach (var classElement in assemblyElement.Elements("class"))
107-
{
108-
HistoricCoverage historicCoverage = new HistoricCoverage(date, tag)
109-
{
110-
CoveredLines = int.Parse(classElement.Attribute("coveredlines").Value, CultureInfo.InvariantCulture),
111-
CoverableLines = int.Parse(classElement.Attribute("coverablelines").Value, CultureInfo.InvariantCulture),
112-
TotalLines = int.Parse(classElement.Attribute("totallines").Value, CultureInfo.InvariantCulture),
113-
CoveredBranches = int.Parse(classElement.Attribute("coveredbranches").Value, CultureInfo.InvariantCulture),
114-
TotalBranches = int.Parse(classElement.Attribute("totalbranches").Value, CultureInfo.InvariantCulture)
115-
};
116-
lock (locker)
117-
{
118-
overallHistoricCoverages.Add(historicCoverage);
119-
}
120-
121-
if (assembly == null)
122-
{
123-
continue;
124-
}
125-
126-
Class @class = assembly.Classes.SingleOrDefault(c => c.Name == classElement.Attribute("name").Value);
127-
128-
if (@class == null)
129-
{
130-
continue;
131-
}
132-
133-
@class.AddHistoricCoverage(historicCoverage);
134-
}
105+
overallHistoricCoverages.AddRange(historicCoverages);
135106
}
136107
}
137108
catch (Exception ex)
@@ -141,6 +112,37 @@ internal void ApplyHistoricCoverage(IEnumerable<Assembly> assemblies, IList<Hist
141112
});
142113
}
143114

115+
private IEnumerable<HistoricCoverage> ParseHistoricFile(IDictionary<string, Class> classes, XDocument document, DateTime date, string tag)
116+
{
117+
ConcurrentBag<HistoricCoverage> historicCoverages = new ConcurrentBag<HistoricCoverage>();
118+
Parallel.ForEach(document.Root.Elements("assembly").ToArray(), assemblyElement =>
119+
{
120+
string assemblyName = assemblyElement.Attribute("name").Value;
121+
foreach (var classElement in assemblyElement.Elements("class"))
122+
{
123+
HistoricCoverage historicCoverage = new HistoricCoverage(date, tag)
124+
{
125+
CoveredLines = int.Parse(classElement.Attribute("coveredlines").Value, CultureInfo.InvariantCulture),
126+
CoverableLines = int.Parse(classElement.Attribute("coverablelines").Value, CultureInfo.InvariantCulture),
127+
TotalLines = int.Parse(classElement.Attribute("totallines").Value, CultureInfo.InvariantCulture),
128+
CoveredBranches = int.Parse(classElement.Attribute("coveredbranches").Value, CultureInfo.InvariantCulture),
129+
TotalBranches = int.Parse(classElement.Attribute("totalbranches").Value, CultureInfo.InvariantCulture)
130+
};
131+
historicCoverages.Add(historicCoverage);
132+
if (classes.TryGetValue(this.GetFullClassName(assemblyName, classElement.Attribute("name").Value), out var @class))
133+
{
134+
@class.AddHistoricCoverage(historicCoverage);
135+
}
136+
}
137+
});
138+
return historicCoverages;
139+
}
140+
141+
private string GetFullClassName(string assemblyName, string className)
142+
{
143+
return $"{assemblyName}+{className}";
144+
}
145+
144146
private XDocument LoadXDocument(string file)
145147
{
146148
using (var stream = this.historyStorage.LoadFile(file))

0 commit comments

Comments
 (0)