cake icon indicating copy to clipboard operation
cake copied to clipboard

Cake Build Tool's Startup is Slow - 25s (64% overhead)

Open WalkerCodeRanger opened this issue 6 years ago • 14 comments

What You Are Seeing?

When I clone the example repo, and time the build command, there is A LOT of overhead time on the build even after repeated builds so it has had a chance to download everything and cache anything. That is, a lot of the time is spent loading cake and compiling the build script. See below for exact numbers.

What is Expected?

There should be less than a couple seconds of overhead from the build tool. 25s might be acceptable for a build on a build server, but it is unacceptable for a workflow where you repeatedly run the build locally each time you need feedback on compilation errors. You can't be waiting half a minute for every build to even start.

What version of Cake are you using?

v0.28.0

Are you running on a 32 or 64 bit system?

64 Bit

What environment are you running on? Windows? Linux? Mac?

Windows 7 Pro

Are you running on a CI Server? If so, which one?

No

How Did You Get This To Happen? (Steps to Reproduce)

  1. Clone the example repo
  2. Run a build ./build.ps1, ignore the timing of this build, it is downloading things for the first time etc.
  3. Run a second build using the powershell command to time it Measure-Command { ./build.ps1 -Verbosity Verbose -Verbose | Out-Host }

The end of the build output is:

Task                          Duration
--------------------------------------------------
Clean                         00:00:00.0557395
Restore-NuGet-Packages        00:00:02.5100364
Build                         00:00:07.7906003
Run-Unit-Tests                00:00:03.5055638
Default                       00:00:00.0071490
--------------------------------------------------
Total:                        00:00:13.8690890


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 38
Milliseconds      : 407
Ticks             : 384074655
TotalDays         : 0.000444530850694444
TotalHours        : 0.0106687404166667
TotalMinutes      : 0.640124425
TotalSeconds      : 38.4074655
TotalMilliseconds : 38407.4655

You can see that Cake reported 13.8s total time. But powershell reported 38.4s total time. A difference of almost 25s. Almost all of which comes during the startup of cake. Repeated runs show similar results.

Your development machine may be faster reducing the pain, but it still shouldn't be 64% of the total time.

WalkerCodeRanger avatar Jun 03 '18 13:06 WalkerCodeRanger

I feel this pain. This has been pushing me recently toward the idea of precompiling binaries and distributing them via NuGet feed, turning the Cake script into a glorified settings file.

jnm2 avatar Jun 03 '18 13:06 jnm2

I cloned repo tried the same on my Machine, first run

time ./build.sh
Task                          Duration
--------------------------------------------------
Clean                         00:00:00.0055274
Restore-NuGet-Packages        00:00:02.5795448
Build                         00:00:02.1711037
Run-Unit-Tests                00:00:01.2189825
Default                       00:00:00.0001979
--------------------------------------------------
Total:                        00:00:05.9753563
./build.sh  9.44s user 1.59s system 83% cpu 13.266 total

Next run

Task                          Duration
--------------------------------------------------
Clean                         00:00:00.0054196
Restore-NuGet-Packages        00:00:02.3709420
Build                         00:00:00.7348149
Run-Unit-Tests                00:00:01.1956039
Default                       00:00:00.0002194
--------------------------------------------------
Total:                        00:00:04.3069998
./build.sh  6.96s user 0.71s system 98% cpu 7.773 total

devlead avatar Jun 03 '18 13:06 devlead

WIthout bootstrapper


Task                          Duration
--------------------------------------------------
Clean                         00:00:00.0093852
Restore-NuGet-Packages        00:00:02.3830687
Build                         00:00:00.7219495
Run-Unit-Tests                00:00:01.1815667
--------------------------------------------------
Total:                        00:00:04.2963833
cake build.cake  6.20s user 0.62s system 98% cpu 6.928 total

devlead avatar Jun 03 '18 13:06 devlead

My results on a clean clone of the repository on a 4G mobile connection (I'm currently at a Café).

> time ./build.sh
[OMITTED]
Task                          Duration            
--------------------------------------------------
Clean                         00:00:00.0038619    
Restore-NuGet-Packages        00:00:03.4260819    
Build                         00:00:01.4021285    
Run-Unit-Tests                00:00:00.8172034    
Default                       00:00:00.0001519    
--------------------------------------------------
Total:                        00:00:05.6494276    
./build.sh  8,46s user 0,98s system 60% cpu 15,629 total

patriksvensson avatar Jun 03 '18 13:06 patriksvensson

Tried on a Windows Machine i7 2.8GHz no SSD, previous was on a Mac Pro 2016

1st run

Measure-Command { .\build.ps1 }
Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 11
Milliseconds      : 358
Ticks             : 113589104
TotalDays         : 0.00013146887037037
TotalHours        : 0.00315525288888889
TotalMinutes      : 0.189315173333333
TotalSeconds      : 11.3589104
TotalMilliseconds : 11358.9104

2nd run

Measure-Command { .\build.ps1 }
Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 9
Milliseconds      : 505
Ticks             : 95059788
TotalDays         : 0.000110022902777778
TotalHours        : 0.00264054966666667
TotalMinutes      : 0.15843298
TotalSeconds      : 9.5059788
TotalMilliseconds : 9505.9788

Without bootstrapper

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 6
Milliseconds      : 929
Ticks             : 69299148
TotalDays         : 8.02073472222222E-05
TotalHours        : 0.00192497633333333
TotalMinutes      : 0.11549858
TotalSeconds      : 6.9299148
TotalMilliseconds : 6929.9148

devlead avatar Jun 03 '18 13:06 devlead

Looking at the times where both a total from Cake and from timing the command were provided, even on the much faster machines than mine, it took 2s to 3.5s of overhead and this was 30%-40% of the total time. Also, while an up to date run build time of 7s is much better than what I'm getting on my machine. It is still a very long time if what you want to do is build frequently as you write code to get feedback and that is a starting number for a very simple build.

My concrete suggestions would be:

  • Make the total time reported by cake include as much of the cake startup time as possible. i.e. start the timer first thing in the cake code. (This removes the feeling that you are crazy because the build seems to take longer than reported).
  • Consider adding a step to the cake build task output for this initial start time
  • Investigate whether it would be possible to cache the compilation of the build file similar to how python will cache in .pyc files.
  • Profile Cake to make sure there isn't something that is needlessly wasting time
  • Evaluate whether async code would allow things to be done in parrelel thereby reducing the wallclock time

WalkerCodeRanger avatar Jun 06 '18 00:06 WalkerCodeRanger

If you want continuous real time builds it would probably make sense to have cake process running and have things in a loop, iterations triggered by i.e. user input, file watcher event etc.

Your suggestions sounds like good avenues to pursue, if you to we'll happily review your findings in a PR.

Near future the Cake team has other features prioritized, we might do some refactoring around roslyn script handling, but for now I'll mark this as up for grabs.

devlead avatar Jun 06 '18 13:06 devlead

I got a new laptop:

  • i7-8750H (6 cores)
  • 16 GB RAM
  • Everything on an NVMe SSD drive
  • Plugged in so no throttling due to battery power

First run:

Task                          Duration
--------------------------------------------------
Clean                         00:00:00.0074903
Restore-NuGet-Packages        00:00:03.1880764
Build                         00:00:02.0895781
Run-Unit-Tests                00:00:00.8834263
Default                       00:00:00.0027005
--------------------------------------------------
Total:                        00:00:06.1712716


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 22
Milliseconds      : 813
Ticks             : 228138695
TotalDays         : 0.000264049415509259
TotalHours        : 0.00633718597222222
TotalMinutes      : 0.380231158333333
TotalSeconds      : 22.8138695
TotalMilliseconds : 22813.8695

second run:

Task                          Duration
--------------------------------------------------
Clean                         00:00:00.0134219
Restore-NuGet-Packages        00:00:01.6837056
Build                         00:00:00.4692074
Run-Unit-Tests                00:00:00.7049643
Default                       00:00:00.0016347
--------------------------------------------------
Total:                        00:00:02.8729339


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 6
Milliseconds      : 712
Ticks             : 67123516
TotalDays         : 7.76892546296296E-05
TotalHours        : 0.00186454211111111
TotalMinutes      : 0.111872526666667
TotalSeconds      : 6.7123516
TotalMilliseconds : 6712.3516

Additional runs show similar times.

While this is much faster overall, almost 4 seconds of overhead time seems totally ridiculous on a brand new, gaming laptop. Cake is 58% of the runtime for the second run. Perhaps the actual slow down is network?

WalkerCodeRanger avatar Jun 18 '18 13:06 WalkerCodeRanger

@WalkerCodeRanger These are the same run from my Windows Laptop with about the same specs.

4 seconds "overhead" seems reasonable to me if you take into account what is done (processing files, checking nuget packages, compiling scripts, executing said script)

Task                          Duration
--------------------------------------------------
Clean                         00:00:00.0056246
Restore-NuGet-Packages        00:00:01.0763986
Build                         00:00:01.1507315
Run-Unit-Tests                00:00:00.7000715
Default                       00:00:00.0014587
--------------------------------------------------
Total:                        00:00:02.9342849


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 8
Milliseconds      : 568
Ticks             : 85681928
TotalDays         : 9.91688981481481E-05
TotalHours        : 0.00238005355555556
TotalMinutes      : 0.142803213333333
TotalSeconds      : 8.5681928
TotalMilliseconds : 8568.1928

Second run:

Task                          Duration
--------------------------------------------------
Clean                         00:00:00.0060150
Restore-NuGet-Packages        00:00:00.7813876
Build                         00:00:00.3725292
Run-Unit-Tests                00:00:00.6247090
Default                       00:00:00.0018488
--------------------------------------------------
Total:                        00:00:01.7864896


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 5
Milliseconds      : 68
Ticks             : 50683407
TotalDays         : 5.86613506944444E-05
TotalHours        : 0.00140787241666667
TotalMinutes      : 0.084472345
TotalSeconds      : 5.0683407
TotalMilliseconds : 5068.3407

patriksvensson avatar Jun 18 '18 14:06 patriksvensson

@WalkerCodeRanger said... almost 4 seconds of overhead time seems totally ridiculous on a brand new,

Out of interest... what would you deem as acceptable?

gep13 avatar Jun 18 '18 14:06 gep13

This is what I got on a 2 year old Intel nuc i7 with SSD

First run:

Task                          Duration
--------------------------------------------------
Clean                         00:00:00.0160194
Restore-NuGet-Packages        00:00:03.1897614
Build                         00:00:02.8009840
Run-Unit-Tests                00:00:01.3675296
--------------------------------------------------
Total:                        00:00:07.3757996


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 17
Milliseconds      : 922
Ticks             : 179221536
TotalDays         : 0.000207432333333333
TotalHours        : 0.004978376
TotalMinutes      : 0.29870256
TotalSeconds      : 17.9221536
TotalMilliseconds : 17922.1536

Second run:

Task                          Duration
--------------------------------------------------
Clean                         00:00:00.0168614
Restore-NuGet-Packages        00:00:01.7663950
Build                         00:00:00.7507376
Run-Unit-Tests                00:00:01.0086823
--------------------------------------------------
Total:                        00:00:03.5446485


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 9
Milliseconds      : 124
Ticks             : 91245783
TotalDays         : 0.000105608545138889
TotalHours        : 0.00253460508333333
TotalMinutes      : 0.152076305
TotalSeconds      : 9.1245783
TotalMilliseconds : 9124.5783

Sure could be network related. Could be Antimalware/virus kicking in too, in those cases hard to optimize Cake for that.

I have nothing against better performance (and we'll happily look at taking contributions in this area), but IMHO think it's currently good enough for is to put focus elsewhere. Don't think it's totally unacceptable.

devlead avatar Jun 18 '18 15:06 devlead

Reran it on another machine HP Envy i7, 8gbs ram and SSD First run:

Task                          Duration
--------------------------------------------------
Clean                         00:00:00.0157910
Restore-NuGet-Packages        00:00:01.8415308
Build                         00:00:01.8083681
Run-Unit-Tests                00:00:01.1041097
--------------------------------------------------
Total:                        00:00:04.7712985


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 13
Milliseconds      : 344
Ticks             : 133448886
TotalDays         : 0.000154454729166667
TotalHours        : 0.0037069135
TotalMinutes      : 0.22241481
TotalSeconds      : 13.3448886
TotalMilliseconds : 13344.8886

Second run

Task                          Duration
--------------------------------------------------
Clean                         00:00:00.0173817
Restore-NuGet-Packages        00:00:01.5461378
Build                         00:00:00.6896346
Run-Unit-Tests                00:00:00.9825372
--------------------------------------------------
Total:                        00:00:03.2372046


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 8
Milliseconds      : 752
Ticks             : 87528970
TotalDays         : 0.000101306678240741
TotalHours        : 0.00243136027777778
TotalMinutes      : 0.145881616666667
TotalSeconds      : 8.752897
TotalMilliseconds : 8752.897

Out-Host and console output could also have an effect on perf.

Doing a dotnet new console --no-restore

And then Measure-Command { dotnet run | Out-Host } on same machine

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 2
Milliseconds      : 382
Ticks             : 23820180
TotalDays         : 2.75696527777778E-05
TotalHours        : 0.000661671666666667
TotalMinutes      : 0.0397003
TotalSeconds      : 2.382018
TotalMilliseconds : 2382.018

That's a zero dependency console application just containing

Console.WriteLine("Hello World!");

devlead avatar Jun 18 '18 15:06 devlead

I'm currently using Cake in a large project with many subproject where the overhead (of 4 to 5 seconds) gets multiplied by the number of projects. Even if nothing has changed in any of the projects (thus no rebuild necessary and the build passes within milliseconds), This results in a built time of a few minutes when nothing has changed.

jgosmann avatar Dec 18 '18 13:12 jgosmann

I'm seeing in the region of an overhead of ~2s compared per invocation after the first with cake 3.1.0, which is quite a lot on a modern machine

jeremy-visionaid avatar Nov 07 '23 23:11 jeremy-visionaid