'C# ConfigurationBuilder with reloadOnChange=true slows down app startup on Linux by 2.2 seconds (> 1000%). Why?

I have built a little dotnet 6 app (called tester) to experiment with the ConfigurationBuilder() having a slow startup time issue on Linux in a bigger application. I tracked down the issue to reloadOnChange, but I don't understand the problem.

Changing the boolean reloadOnChange parameter to true leads to a HUGE slowdown in startup time and I would like to ask, if I'm doing something wrong or if it may be a dotnet issue?

Build environment

# macOS Catalina 10.15.7 (x64)
dotnet --version
6.0.101

Runtime environment

Since the app is self-contained, the dotnet version should not be too important.

# Ubuntu Linux 18.04.1 (x64)
dotnet --version
6.0.200

Code that leads to slow app startup

var configBuilder = new ConfigurationBuilder();

var configFiles = new[]
{
    Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "appsettings.json"),
    // the files below do not exist, not even the directory - just a fallback
    Path.Combine(Environment.GetFolderPath(UserProfile, DoNotVerify), ".tester/appsettings.json"),
    Path.Combine(Environment.GetFolderPath(ApplicationData, DoNotVerify), "tester/appsettings.json"),
};

foreach (var f in configFiles)
{
    // using the line below works fast like expected
    // configBuilder.AddJsonFile(f, true, false); 
    
    // HUGE slowdown of app startup with second parameter set to true
    configBuilder.AddJsonFile(f, true, true); 
}

var config = configBuilder.Build();
Console.WriteLine("tester");

Project config

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net6.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>

        <LangVersion>10</LangVersion>

        <InvariantGlobalization>true</InvariantGlobalization>
        <PublishSingleFile>true</PublishSingleFile>
        <PublishTrimmed>true</PublishTrimmed>
        <TrimmerRemoveSymbols>true</TrimmerRemoveSymbols>
        <PublishReadyToRun>true</PublishReadyToRun>
        <EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0"/>
        <PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0"/>
    </ItemGroup>

</Project>

Build script

dotnet publish -r linux-x64 --self-contained -c Release -o ./dist tester.csproj
cd dist

with reloadOnChange=true

time ./tester
tester
./tester  1,78s user 2,22s system 93% cpu 4,261 total

with reloadOnChange=false

time ./tester
tester
./tester  0,12s user 0,02s system 88% cpu 0,157 total

macOS startup times are also slower, but not by this amount:

# "slow" version
./tester  0.12s user 0.17s system 95% cpu 0.303 total

# "fast" version
./tester  0.08s user 0.04s system 18% cpu 0.663 total

Result

reloadOnChange=true slows down the app startup on Linux by 2 seconds (>1000%)... in an app with more code the results are even worse (>10 seconds).

What is happening?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source