fsprojects / FSharp.TypeProviders.SDK

The SDK for creating F# type providers
https://fsprojects.github.io/FSharp.TypeProviders.SDK/
MIT License
298 stars 94 forks source link

Merely referencing a type provider package incurs the cost of instantiating the type providers even when they are not used #325

Open cartermp opened 4 years ago

cartermp commented 4 years ago
  1. Create a new F# console app.
  2. Add the latest FSharp.Data package (ensure it is restored at design-time, not build-time).
  3. Build and measure the time it takes.

Repeat the above, but do not add the FSharp.Data package.

You'll observe that the console app without the reference to the package compiles 200ms-500ms faster, depending on your environment (at least that was the diff on a macOS laptop and a windows desktop).

Profiling this a bit more, we see that ~7% of CPU time for one of the compile runs was spent instantiating type providers and ~4% of CPU time was spent injecting provided types and namespaces into the assembly. All overhead associated with this accounts for ~12% of total CPU time for this compile run:

image

This means for a new console app, we're paying a tremendous cost for something that's not being used. These figured may go up or down in subsequent runs, but the order of magnitude is always the same.

This cost eventually becomes insignificant for large and even medium projects.

However, this cost is very notable if you have a large solution made up of numerous small projects that may indirectly reference FSharp.Data as a result of a transitive dependency. We saw this with a customer-submitted trace, where over 100 small projects end up pulling in this dependency. For any given fsc process in the trace, anywhere from 13% to 16% of cpu time for that process was spent instantiating type providers only to dispose of them after never using them.

My opinion is that this is fundamentally a compiler issue, but this is not divorced from my own issues about how type providers work. There is evidently a fix that can be made in the Type Provider SDK to ameliorate this problem, though it is unclear how much.

cartermp commented 4 years ago

ref: https://github.com/dotnet/fsharp/issues/7907