fsharp icon indicating copy to clipboard operation
fsharp copied to clipboard

Now that we have reference assembly support in F# - consider how to use them for FCS and FSharp.Core nuget packages

Open KevinRansom opened this issue 2 years ago • 1 comments

Will improve compilation times in some scenarios. May help with package size.

KevinRansom avatar Jun 16 '22 21:06 KevinRansom

@KevinRansom is there anything the community can do to assist you here?

nojaf avatar Jul 11 '22 11:07 nojaf

Okay, I have taken another look at this:

Download size Adding reference assemblies to FSharp.Core introduces a considerable spike in the size of the nuget package, both for download and on-disk.

  • Without ref assemblies FSharp.Core is: 2511 Kb
  • With reference assemblies this rises to: 3770 Kb

This is approximately a 50% increase in size of the download package. Additionally because we embed FSharp.Core in the dotnet sdk this will increase the size of the download for the dotnet sdk by approx 1260 Kbytes.

Download sizes impose a burden on developers in terms of time and bandwidth costs.

On-disk size The on-disk size of the nuget package also increases:

  • Without ref assemblies the on disk size of FSharp.Core expanded is: 12.0 MB (12,673,024 bytes)
  • With Ref Assemblies the on disk size of FSharp.Core expanded is: 15.2 MB (15,958,016 bytes)

This cost is incurred when using cloud based VMs, because the space required is enlarged.

Reference assemblies, compile time, and working set! To evaluate this, I created a trivial F# console app, built a response file and compiled with the --times options about 50 times with reference assemblies and 50 times without, scraped the output shoved it in Excel and got some averages

--times produced output similar to:

--------------------------------------------------------------------------------------------------------
|Phase name                          |Elapsed |Duration| WS(MB)|  GC0  |  GC1  |  GC2  |Handles|Threads|
|------------------------------------|--------|--------|-------|-------|-------|-------|-------|-------|

warning FS0075: The command-line option 'times' is for test purposes only
|Import mscorlib+FSharp.Core         |  0.3684|  0.3023|    155|      0|      0|      0|    259|     28|
|Parse inputs                        |  0.4351|  0.0577|    161|      0|      0|      0|    281|     32|
|Import non-system references        |  0.4400|  0.0005|    161|      0|      0|      0|    281|     32|
|Typecheck                           |  0.6835|  0.2361|    197|      0|      0|      0|    282|     32|
|Typechecked                         |  0.6884|  0.0004|    197|      0|      0|      0|    282|     32|
|Write Interface File                |  0.6928|  0.0000|    197|      0|      0|      0|    282|     32|

For our purposes:

|Import mscorlib+FSharp.Core
|Write .NET Binary

are the interesting items: Write .NET Binary because the elapsed time and working set is for the full compile, and Import mscorlib+FSharp.Core because it's duration and working set are the values most likely impacted by reference verses implementation assembly import.

So for implementation assemblies the values were:

  • Import average duration: 0.280525 seconds
  • Import working set: 156.6667
  • Full elapsed time: 1.04067
  • Full working set: 230.0179 MB

So for reference assemblies the values were:

  • Import average duration: 0.279715
  • Import working set: 155.0984
  • Full elapsed time: 1.034142
  • Full working set: 228.95

As you can see by these numbers, the performance benefits are very small indeed, I am proposing that for the forseeable future we do not burden the FSharp.Core nuget package with reference assemblies. Given the download and on disk costs that everyone would incur by including them.

Please let me know if you think this is erroneous conclusion or if you are aware of scenarios where FSharp.Core reference assembly deployment would be beneficial, and we can revisit this proposal.

If anyone is terribly interested in checking the working here are the raw files The csv lib_write.csv ref_results.csv lib_results.csv ref_write.csv

The raw compiler output ref.txt lib.txt

Here is a nuget package with ref assemblies: It was renamed to zip for uploading. FSharp.Core.7.0.300-dev.nupkg.zip

KevinRansom avatar May 11 '23 20:05 KevinRansom

Hi Kevin, thanks for this write up. I tried a similar setup on my machine and got similar results. Overall for F# Core the benefit doesn't seem to outweigh the additional download cost.

nojaf avatar May 12 '23 07:05 nojaf

closing

KevinRansom avatar May 12 '23 19:05 KevinRansom