sdk: dotnet run of hello world takes way too long
Reported by @migueldeicaza
Steps to reproduce
- dotnet new console
- dotnet build
- dotnet run
Expected behavior
dotnet run executes fast, nearly the same as calling dotnet <pathToDll>
Actual behavior
dotnet run is slow, about 3 seconds on my machine. It’s consistently this slow, even when it doesn’t need to rebuild.
It appears that run is calling msbuild twice before actually running the app:

Can’t we have a fast-path here that bypasses MSBuild? It seems like we’ve optimized for incremental build via the run command which I’m not sure is really the primary workflow for run (but I may be wrong).
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 30
- Comments: 60 (28 by maintainers)
I believe
dotnet run --no-buildwill help here. Maybe it should be the default.We’re investigating CLI performance for the commands frequently used during development as part of .NET 6 and we definitely expect to get improvements to this very common scenario of running a simple app via
dotnet run.As it stands today, using a nightly build of .NET 6.0-preview.3, a
dotnet runon a “Hello, World!” console app takes about 1.3-1.4 seconds on my machine, after a warm-up run or two. Running the app directly takes ~60ms, so thedotnet runoverhead is practically the entire time, which is mostly spent in the the execution of the restore and build itself.Progress on this work can be followed at https://github.com/dotnet/msbuild/issues/5876
It is quite slow when I just run the
Console.WriteLine("Hello World!");on Macos.If you want to run your application after it’s already been compiled, do this:
dotnet bin\debug\netcoreapp2.0\ncc.dllThis is much quicker than using dotnet run, with or without --no-build, because dotnet doesn’t need to spending time figuring out which file contains the startup object.
I think the interesting thing here, is that if MSBuild was a closed system, I’m pretty damn confident we could make this blazingly fast. It’s not. By design, it’s an open extensible system and any package, SDK, project can and do supplement the build process. We have to be able to identify performance issues and fix each individual step in the process and do it in a way that makes sure you projects still build in the same ways. It’s challenging but its really rewarding to see the 10s of devs involved in this pipeline to all rally around a single goal to make builds as fast as possible.
1.8s: I’d expect that to be closer to0.344s@perlun That’s pretty much how the underlying build framework (MSBuild) works.
“Incremental Build” refers to additional builds started after an initial build. During this “incremental build”, steps like compiling C# code can be skipped if the output is “up to date” (when outputs of a step are not older than the inputs to the step).
The recent efforts of the team included both “classic perf work” on existing code (e.g. a community PR made MSbuild’s directory scanning much faster) as well as reducing duplicated work in incremental builds - loading cached outputs if the inputs didn’t change. This also makes incremental builds much faster even if C# code needs to be recompiled, but maybe your referenced NuGet packages and other projects didn’t change and MSBuild doesn’t need to resolve potential conflicts of same assemblies in different versions again, or search for additional dependencies it found in the first build.
Especially when whole windows start in ~20 seconds, and cold run of winword taking 3 seconds. That 4seconds to start the empty app is… a little bit too much… Mostly looks like it dumping the whole HDD to the cloud…
Find myself in the same boat here. Used C# with VS back in the 2006 era or so and loved the rapid development experience coupled with the IDE. I suspect VS was background compiling files as I changed them.
Now I find myself enjoying C# + dotnet while using MonoGame, but the dev experience is definitely hindered by the slow compile + launch even on very recent hardware.
Yeap, totally understood that there’s more going on, but you hit the nail on the head with regards to “similar to F5”… hitting F5 I’m sub 1 second and that’s including an attached debugger, so 4-5 seconds without the debugger makes for a frustrating dev experience (incidentally, no build and no restore options didn’t help).
Anyway, just adding weight as it’s putting me off that particular dev experience.
@ericstj ,
dotnet code.dllis fast. butdotnet run code.dllis slow. I think it is easy to reproduce by yourself.Hi @ericstj ,
I created the console project with
code.cs. then rundotnet run code.cs. It takes a few seconds to finish. I expect it could be done in 50ms.code.cs
code.csproj
To give a new user’s perspective: I just downloaded .net core today on my arch machine. Got here for the same reason as OP -
dotnet runis unexpectedly slow.--no-buildhas an acceptable time though it’s still not instant which is what I expect on subsequent runs. I think it’s worth noting the first time I ran the command I wasn’t surprised because I suspected it was due to building the executable. Subsequent runs however did surprise me.Edit: I don’t mean to infer my use-case should be supported or that my expectation speaks for everyone.
Worth pointing out there’s already
dotnet run --no-buildtoo as a quick way to just run the last compilation. Perhaps a short alias could be introduced for that if folks feel that scenario is common enough to warrant it, e.g.dotnet run -nbOriginal poster here. Just sharing my opinion in why I originally opened this.
Dotnet run does a full incremental build and I didn’t expect that. I wanted something faster, if even just a hueristic like “has any build been done” rather than a full incremental.
I expect a full incremental build to take time, and I think the time it takes is reasonable.
I also think the time for a direct run of the output is reasonable.
AOT is great, and did exist before .NETCore did (UWP: .NETNative) but that’s not really going to have an impact here. The bottle neck is not JIT it’s IO for the incremental build.
If folks don’t feel like changing dotnet run to use a lighter weight hueristic is something we want to do then I suggest closing this issue and opening other issues more focused on specific perf issues they are facing.
Just started learning C#, i’m on a low end machine atm, and i´m already here. I´m very surprised that
dotnet runis that slow. Since most of other programming languagues that i work with, that are compile to binary have way faster ‘hello world’ compilation times.One thing that i noticed is that build and run the exe is faster than just the run command, which is odd: ( Not the very first build, runned multiple times make sure its cached )
timecmd dotnet run00:00:03.38timecmd dotnet build && bin\Debug\netcoreapp3.1\cs.exe00:00:02.32( and off course, first time builds are way slower )I´m very confused.
Every refresh of the hello world 3.0-preview7 with angular through UseProxyToSpaDevelopmentServer takes at least 4.5 seconds for me:
As a heads up, more improvements have been made in Preview 2 - https://blogs.msdn.microsoft.com/dotnet/2018/04/11/announcing-net-core-2-1-preview-2/.
I’ll let the graph speak for itself:
I’m in the exact same position as you and had the same thought! Can this issue be resolved, or is it just something we must get used to?
On a separate note, I am pushing for https://github.com/dotnet/cli/issues/2960 to get implemented in
2.1. In general - allow the CLI to be configurable. Once that happens, a configuration that could be set would be “what defaultdotnet runexperience do you want?”. Users who know they will always build before they calldotnet runcan configure it to be--no-build. Users who don’t want to bother with ensuring their project is already built before calling run can configure it to be--ensure-built.Then it is just a matter of picking the default/unconfigured option and letting users change it if the default isn’t what they want.
Not if user expects
runto do only a run without a build… The workaround is already to run with --no-build or point the host directly at the application: we don’t need more workarounds. This is issue is about validating the assumption that the majority of users expectrunto also do a build. I’ve seen enough cases where people don’t expect this to question that assumption.Furthermore, the console spew is so minimal that the user doesn’t even realize they are getting an incremental build + run. Even fixing that could make it feel a bit more natural. As it is now it just looks like we’re incredibly slow to
runhelloworld.@livarcocc do we know the cause? if no i’d like to do some performance profile for this case