danielpalme / ReportGenerator

ReportGenerator converts coverage reports generated by coverlet, OpenCover, dotCover, Visual Studio, NCover, Cobertura, JaCoCo, Clover, gcov or lcov into human readable reports in various formats.
https://reportgenerator.io
Apache License 2.0
2.65k stars 283 forks source link

Optimise memory allocations in `HtmlRenderer`. #695

Closed afscrome closed 1 month ago

afscrome commented 2 months ago

This is mainly done by avoiding creating additional StringBuilders and writing direct to the TextWriter where possible. Where StringBuilders are still needed, they're pooled and reused

Saves on the amount of allocated memory and time paused for GC.

I haven't measured a huge improvement in end to end report generation (maybe a second, but hard to say if that's within run to run variance), however reduction in allocations helps and this change does have measurable impacts when combined with my next PR.

Below are the perfview Results with my playground - built on top of the app from #691 with an an additional call to ReportGenerator.GenerateReport.

// Generate the html report with custom configuration for report generator.
var reportGeneratorConfig = new ReportConfigurationBuilder().Create(new Dictionary<string, string>() {
                { "targetdir", targetDir },
                { "sourcedirs", ".\\src" },
                { "reporttypes", "HtmlInline_AzurePipelines" }
            });

var generator = new Generator() { };
var settings = new Settings() { };

stopwatch.Restart();
generator.GenerateReport(reportGeneratorConfig, settings, new RiskHotspotsAnalysisThresholds(), results);

Console.WriteLine($"ELAPSED: {stopwatch}");

Before

  • CommandLine: ".\ReportGenerator\src\Playground\bin\Debug\net8.0\Playground.exe"
  • Runtime Version: V 8.0.824.36612
  • CLR Startup Flags: 8388611
  • Total CPU Time: 38,443 msec
  • Total GC CPU Time: 1,666 msec
  • Total Allocs : 8,378.712 MB
  • Number of Heaps: 1
  • GC CPU MSec/MB Alloc : 0.199 MSec/MB
  • Total GC Pause: 2,567.9 msec
  • % Time paused for Garbage Collection: 8.1%
  • % CPU Time spent Garbage Collecting: 4.3%
  • Max GC Heap Size: 335.820 MB
  • Peak Process Working Set: 395.698 MB
  • Peak Virtual Memory Usage: 2,480,960.369 MB

After

  • CommandLine: ".\ReportGenerator\src\Playground\bin\Debug\net8.0\Playground.exe"
  • Runtime Version: V 8.0.824.36612
  • CLR Startup Flags: 8388611
  • Total CPU Time: 28,247 msec
  • Total GC CPU Time: 1,183 msec
  • Total Allocs : 2,938.748 MB
  • Number of Heaps: 1
  • GC CPU MSec/MB Alloc : 0.403 MSec/MB
  • Total GC Pause: 1,348.8 msec
  • % Time paused for Garbage Collection: 6.2%
  • % CPU Time spent Garbage Collecting: 4.2%
  • Max GC Heap Size: 352.258 MB
  • Peak Process Working Set: 417.976 MB
  • Peak Virtual Memory Usage: 2,480,959.902 MB