Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

F# compiler is really slow when trying to compile .net8.0 project with SDK 8.0.303 #17501

Closed
NogginBops opened this issue Aug 6, 2024 · 21 comments
Labels
Area-Compiler Compiler-related issues which don't belong to other categories Bug Impact-High (Internal MS Team use only) Describes an issue with extreme impact on existing code.
Milestone

Comments

@NogginBops
Copy link

Repro steps

Provide the steps required to reproduce the problem:

  1. Clone this specific commit: https://github.com/BoyBaykiller/opentk/tree/5c9dc6e6f0ec4c911fe05357dbfccc7e81d1842f
  2. Try to compile this test project using dotnet build -v:n .\tests\OpenTK.Tests\OpenTK.Tests.fsproj

Expected behavior

The compiler should compile the project (this particular commit has a runtime error, but that shouldn't matter).

Actual behavior

The compiler never finishes compiling the project.

Known workarounds

Switching to .net6.0 fixes the issue.

Related information

I also tried targeting and compiling the project with SDK Version: 9.0.100-preview.6.24328.19 and I still get the hang.

Provide any related information (optional):

  • Operating system: Windows 10
  • .NET Runtime kind (.NET Core, .NET Framework, Mono): .NET Core 8.0.303
  • Editing Tools (e.g. Visual Studio Version, Visual Studio): Visual Studio 2022 Version 17.10.5
@github-actions github-actions bot added this to the Backlog milestone Aug 6, 2024
@vzarytovskii vzarytovskii modified the milestones: Backlog, August-2024 Aug 7, 2024
@vzarytovskii vzarytovskii added the Impact-High (Internal MS Team use only) Describes an issue with extreme impact on existing code. label Aug 7, 2024
@vzarytovskii
Copy link
Member

vzarytovskii commented Aug 7, 2024

So, the bad news is that I can't reproduce it on my mac, on both net7.0 and net8.0 as targets, compilation takes about a minute (47-55 seconds) on my machine (M2 macbook). net6.0 in main with the same SDK (8.0.100) takes about 4 seconds, which leads me to believe that it is the same sort of issue as described in fsprojects/Fleece#146.

TL;DR of the issue is: around .NET7 BCL rolled out "Static abstracts in interfaces" feature (which led to much bigger interfaces hirearchy), at the same time we rolled out support for static abstracts as well as some changes to SRTPs. And what I think is happening is that once you introduce new BCL, some of the functionality in your tests is making typechecking go brrr, and performance degrades significantly, see discussion in the issue above, as well as Don's comment in fsharp/fslang-design@71cd2e0.

Conclusion: with all this in mind, the the best current course of action (for us or contributors) would be to:

  1. Take current compiler from main.
  2. Build it (Release).
  3. Create a global.json file pointing to latest .NET9 SDK (preview 6 at the moment of me commenting it).
  4. Include it in the project from OP (tests project, from master branch, point to custom compiler via UseLocalCompiler.Directory.Build.props importing).
  5. Profile it with net6.0 (default) target.
  6. Change target to net8.0 (or switch branch to otk5-add-matrx-simd-equal, bba4019df27b0a54ff48ca2205d681dbe990824b at the moment of me commenting it).
  7. Include custom compiler there again. Profile it again.
  8. See what's different/what's wrong.
  9. Try to make it better.

As a temporary workaround(s), there were some comments from @gusty in the original issue in Fleece, which might help.

@vzarytovskii
Copy link
Member

The worst part is that the more people will move to net8.0 as TFM, the more people might hit this issue. I will try to collect some profiles once I have some free time, unless someone will beat me to it.

@vzarytovskii
Copy link
Member

vzarytovskii commented Aug 7, 2024

Profiles for

  1. master branch with tests project upgraded to net6.0:
    net6.zip
  2. otk5-add-matrx-simd-equal branch built with no changes (net8.0):
    net8.zip

Running via .NET9p6 runtime host, with net8 SDK assemblies, on latest main of compiler.

In case if someone wants to look at it.

@vzarytovskii
Copy link
Member

vzarytovskii commented Aug 7, 2024

Compiler spent a minute (out of ~2 under profiling) in just getting interfaces for all types:
image

Additionally, some type directed conversions are involved:
image

(I presume, when we try to find conversions we need to traverse all interfaces)

@vzarytovskii
Copy link
Member

I will experiment with caching stuff more once I'm off of work.

@NogginBops NogginBops changed the title F# compiler hangs when trying to compile .net8.0 project with SDK 8.0.303 F# compiler is really slow when trying to compile .net8.0 project with SDK 8.0.303 Aug 8, 2024
@abonie abonie added Area-Compiler Compiler-related issues which don't belong to other categories and removed Needs-Triage labels Aug 19, 2024
@T-Gro T-Gro self-assigned this Sep 5, 2024
@T-Gro T-Gro modified the milestones: August-2024, September-2024 Sep 5, 2024
@vzarytovskii vzarytovskii self-assigned this Sep 6, 2024
@T-Gro T-Gro removed their assignment Sep 9, 2024
@vzarytovskii vzarytovskii moved this from New to In Progress in F# Compiler and Tooling Oct 29, 2024
@vzarytovskii vzarytovskii removed their assignment Oct 31, 2024
@NogginBops
Copy link
Author

Is it possible to link the changes that fixes this issue?

@vzarytovskii
Copy link
Member

Is it possible to link the changes that fixes this issue?

#17668 it didn't link for some reason

@hyazinthh
Copy link

Is there an ETA on this? Has been bugging me for months and makes working in some repositories pretty much impossible.

@vzarytovskii
Copy link
Member

vzarytovskii commented Nov 20, 2024

Is there an ETA on this? Has been bugging me for months and makes working in some repositories pretty much impossible.

It will be released with 9.0.200 in January, but will be under preview flag, and only for compilation.

@hyazinthh
Copy link

Is this also going to be backported to 8.0? We compile all our repositories with the .NET 8 SDK due to this issue.

@vzarytovskii
Copy link
Member

Is this also going to be backported to 8.0? We compile all our repositories with the .NET 8 SDK due to this issue.

It will be up to the team. @T-Gro, @KevinRansom thoughts?

@T-Gro
Copy link
Member

T-Gro commented Nov 20, 2024

Is this also going to be backported to 8.0? We compile all our repositories with the .NET 8 SDK due to this issue.

Can you elaborate please?
The issue is about a binary format mismatch between NET6 and NET7.

Are you encountering the same/similar between NET8 and NET9 ?
If yes, I would prefer to fix that (to benefit everyone) instead of backporting the caching layer.

We would definitely appreciate your support in identifying a problem which prevents you from building using .NET9 SDK.

@hyazinthh
Copy link

We could probably use .NET 9 for our builds if we absolutely had to, I'm not aware of any current incompatibilities like with 6 and 7.

But back when .NET 7 was released we had to force the build system in dozens of repositories to .NET 6. Now with the phasing out of .NET 6 we thought it'd be a good idea to keep using the LTS version of the SDK to be resilient against any issues that might arise with the .NET 9 SDK. Also seeing that the issue has never been addressed made us a bit cautious. So in short, we opt to use the .NET 8 to be on the safe side.

But I think that's beside the point anyway. I'd expect a major regression like this one to be fixed in the current LTS version.

@T-Gro
Copy link
Member

T-Gro commented Nov 20, 2024

For this bug, it's has not been a regression of the compiler - it was a consequence of many interface layers added to numeric types in NET. The cache has been added as a brand new feature, even under the language version flag for langversion=preview and NET10 eventually.

In general, we are not backporting preview language features into older versions of the language.

I do understand the desire, but a manually cherry-picked migration of this feature into NET8 SDK, pretending this is a NET8 feature and not a preview feature, would only add more risks. It would also slow down fixes in this area due to inability to automatically backport changes once a conflict like this would be created.

@charlesroddie
Copy link
Contributor

even under the language version flag for langversion=preview and NET10 eventually.

There is some urgency about this for F#. Being unusably slow compiling and providing intellisense for dotnet8 and dotnet9 isn't an acceptable situation. dotnet8 and dotnet9 are the only supported versions of dotnet.

Once it's fixed (in both compilation and tooling) it needs fix dotnet9 compilation without the need to set preview flags. For every developer that discovers the preview flag there will be 10 that don't and end up with a terrible experience of using F#.

Our team is lucky because we have a lot of things that are or can be netstandard. But again, few teams will know that that is a workaround (and we didn't and had a bad experience for several months after moving to net8/net9 - we assumed it as a bad VS update).

@haraldsteinlechner
Copy link

haraldsteinlechner commented Apr 7, 2025

Well, i totally understand backporting larger fixes is problematic, but i second @charlesroddie and i just want to underline the importance of "trustworthy" LTS versions, especially important for people working in larger ecosystems.

That said, I'm a long term F# advocate and pushed technologies towards F# in various companies. I'm using it for teaching, and my company of course also is mostly F#.
Performance regressions make all of this hard. And it reduces trust in the platform for everyone involved in technical decisions. There is always a long latency from defect detection to really having it available in the wild. For this reason there is always the idea to stick with LTS not to stall the whole ecosystem waiting for a F# compiler problem to go away for end-users.

I see that there are technical stories behind it but from a user perspective going from already slow 24s for a particular project to 76 is a bummer (and users would actually identify it as a regression not caring about technical side). It does not sound like this severe but it is. Arguing for F# with its slow compiler is already hard enough - going to 76 is a huge one.

Slow intellisense is so frustrating for new users also. With a large ecosystem and libraries (not just apps), such things take for a long time to clear out, e.g. this one, quite mild will be a trap for users for months until all libraries and examples get fixed.

@haraldsteinlechner
Copy link

Maybe we could assemble a set of "hard-to-compile" real-world files/projects (if appreciated). Maybe this could be part of a performance test suite @hyazinthh @krauthaufen @luithefirst

@majocha
Copy link
Contributor

majocha commented Apr 7, 2025

IIRC Vlad did a fix for this but enabling it in tooling depends on this #18190

@T-Gro
Copy link
Member

T-Gro commented Apr 7, 2025

Indeed, this is now only implemented for standalone CLI compilation.
I will follow up on that PR to progress it to tooling as well.

This regression was particularly difficult to spot because it came "from the side" by the static abstracts feature and the implosion of interface hierarchies in size this has caused in the BCL.

@haraldsteinlechner: I have a dream of having a suite of pluggable compiler-CI extensions, ideally just a list of triplets: repo url, commit hash (can be updated on demand), and a build+test script to run. Designed exactly for spotting compiler regressions for popular/important/"special" libraries in the ecosystem.

@baronfel
Copy link
Member

baronfel commented Apr 7, 2025

@T-Gro you should talk to Jared about his complog tool. I think Roslyn uses it in part to make it easy to extract out these kind of calls into something that can be independently tested across versions.

@haraldsteinlechner
Copy link

@T-Gro thanks for clarification and the great work. Yes i will set something up!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compiler Compiler-related issues which don't belong to other categories Bug Impact-High (Internal MS Team use only) Describes an issue with extreme impact on existing code.
Projects
Archived in project
Development

No branches or pull requests

9 participants