Skip to content

[Performance] ProjectTagViolationDetector reads and parses XML file for every reference × rule combination #51

@mfogliatto

Description

@mfogliatto

Description

ProjectTagViolationDetector.GetViolationsFrom() calls this.projectTagProvider.GetProjectTag(referenceContext.Reference) inside a nested loop (for each rule × each reference). ProjectTagProvider.GetProjectTag() loads and parses the XML project file from disk on every call.

Affected Files

  • src/ReferenceCop/Detectors/ProjectTagViolationDetector.cs (line ~30, inside nested loop)
  • src/ReferenceCop/Providers/ProjectTagProvider.cs (entire GetProjectTag method — XDocument.Load() per call)

Impact

For a solution with R rules and N project references:

  • R × N file I/O operations and XML parses, even though the same project files are read repeatedly
  • For a typical solution (e.g., 20 rules, 50 references), this means 1,000 XML file parses per build, most of them redundant
  • Build-time analyzer, so this directly impacts developer inner loop

Suggested Optimization

Cache the project tag per file path:

public class ProjectTagProvider : IProjectTagProvider
{
    private readonly ConcurrentDictionary<string, string> _cache = new();

    public string GetProjectTag(string projectFilePath)
    {
        return _cache.GetOrAdd(projectFilePath, path =>
        {
            if (!File.Exists(path)) return UnknownProjectTag;
            var projectFile = XDocument.Load(path);
            return projectFile
                .Descendants(PropertyGroupNode)
                .Elements(ProjectTagNode)
                .FirstOrDefault()?.Value ?? UnknownProjectTag;
        });
    }
}

This reduces N×R file reads to at most N (one per unique project file), typically much fewer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    performancePerformance optimization

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions