Skip to content

Improving dotnet run file.cs performance #48011

Open
@DamianEdwards

Description

@DamianEdwards

Issue to capture data, ideas, etc. regarding improving the DX performance of the new dotnet run file.cs feature. Specific work item issues can be added as sub-issues to this epic.

Some baseline numbers

Windows & WSL2 numbers measured on the same machine. Mac numbers measured on an M4 Mac Mini. Both Windows & Mac machines enrolled in corporate device management.

Command OS Time Notes
dotnet --list-sdks Windows ~12-20ms No managed runtime involved so extremely fast listing of SDK directories in known location
dotnet --list-sdks Ubuntu via WSL2 ~5ms
dotnet --list-sdks macOS ~17-20ms
dotnet run --help Windows ~200ms Loads the CLI and dispatches to the run command. Basically as fast as an invocation of dotnet run can be. Anything we can do to reduce this should improve the DX of dotnet run file.cs too.
dotnet run --help Ubuntu via WSL2 ~112ms
dotnet run --help macOS ~144ms
dotnet exec hello.dll Windows ~32ms Full run of a built hello world console app (default Debug configuration). Anything more than this is DX overhead.
dotnet exec hello.dll Ubuntu via WSL2 ~31ms Interestingly this is the only case where the number is basically the same between Windows and Ubuntu
dotnet exec hello.dll macOS ~54ms This was consistently slower than launching on my Windows/WSL2 machine

Windows vs. Linux (WSL)

I did some comparisons of running dotnet run hello.cs on various Windows 11 machines (both Intuned and not Intuned, desktops and laptops) vs. running it in a WSL2 Ubuntu instance on those same machines. In each case, the .NET CLI was installed into the Linux instance and the test C# files were in the Linux file system directly rather than accessed via the host.

In all cases, running dotnet run hello.cs in the WSL instance was significantly faster, usually around 40-50% faster but sometimes even more. On my laptop It usually took around 2-2.5 seconds in Windows, and in WSL it took only 1.1-1.2 seconds. On my desktops the numbers were more like Windows 1.5 seconds, WSL 1.0 seconds.

This pattern was consistent whether running with real-time antivirus inspection enabled or disabled (either via directory exclusions or by completely disabling it).

Not sure what action we can take other than profiling to help isolate the differences but the data seemed interesting to record.

Build vs. no-build

The overhead of performing a build (i.e. using MSBuild) during dotnet run hello.cs is significant. Directly comparing dotnet run hello.cs to dotnet run hello.cs --no-build results in times like the following (all measurements taken on the same machine):

Command OS Time
dotnet run file.cs Windows ~1.5s
dotnet run file.cs --no-build Windows ~630ms
dotnet run file.cs Ubuntu via WSL2 ~830ms
dotnet run file.cs --no-build Ubuntu via WSL2 ~330ms

It seems it will be extremely beneficial to explore ways in which we can speed up the build step, or completely avoid it when possible, given the more scoped set of changes that might occur between runs of a specific C# file, e.g.:

  • Enabling of the MSBuild server is planned later in the .NET 10 cycle & could improve build times
  • Caching of the RAR task outputs has been discussed and could improve build times
  • runfile could completely avoid running build if there are no implicit build files and no C# file directives (i.e. #:sdk and #:package) as the set of inputs to the compiler is fixed (e.g. at CLI build time) and could be invoked directly
  • runfile could implement up-to-date checks (modified time stamps, content hashes) on build-effecting inputs like implicit build files, C# files, and C# file directives and when no build-impacting changes are detected directly invoke the compiler using cached arguments from the previous run.
    • Adding or deleting a C# file would likely need to be considered a change that requires re-invoking build as globs are evaluated as part of the build, but non-directive changes to C# files should be fine

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-CLIArea-run-fileItems related to the "dotnet run <file>" effort

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions