-
Notifications
You must be signed in to change notification settings - Fork 789
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
Compilation gets much slower when using many computation expressions #14429
Comments
I think this is a pretty decent repro: The response files are set up for my laptop.
run the first (non-ce) using:
Observe:
Repeat for ce response:
observe:
from .8 up to 2.6 seconds with a constant about a half second start up penalty in each case would tend to indicate, some super expensive operations happening in the CE case. |
In my case what really slowed down highlighting and checking was adding more cases to yield-combine combo. Idea is simple: if you yield some items then you can yield only those, I'd you yield other then only other. So before there was only one "type-path" in my CE and it was super fast. After I've implemented a new yield-combine-... to make an additional "type-path" intellisense and highlighting started to show considerable amount of lag By "type-path" I mean resulting type in CE operations, in this example it's ReactElements. In my case I have roughly speaking ReactElements and ReactElements2. |
Similar issue hanppens to my library too: #12723 |
Yes, this is the same phenomena. I want to have a look at this eventually to see if the resolution approach could be tuned while maintaining the same behavior, but I can already see this is a risky path. If I fail to improve it in general (very possible), I want to at least come up with a recommendation to keep things fast. |
@albertwoo It's funny that your CE in question is blazor-based. So is mine :) I had to introduce different types/overloads to split css and elements (e.g. if you do In your case I see from that issue is that you don't do this kind of split but perf is still not okay? |
@En3Tho yes it is for blazor. Here is my repo: https://github.com/slaveOftime/Fun.Blazor div {
class' "..."
onclick (fun _ -> ())
h1 { "foo" }
p { "bar" }
} But after I found the performance issue, I introduced a CustomOperation "childContent", which can improve the performance a lot: div {
class' "..."
onclick (fun _ -> ())
childContent [
h1 { "foo" }
p { "bar" }
]
} But still, CE DSL is slow for compile and autocomplete when project grows. There are definitely some places to improve, for example, one character change in a string can make the whole solution (multiple projects) rebuild which is so annoying, expecially there is not hot-reload supported in fsharp. |
I also found that the number of CustomOperations which ared defined in the CE builder will impact the compilation speed a lot. Maybe fsharp compilier can add some cache to improve the lookup for CustomOperations. |
There is another thing which may also be related, for example, in below picture, the CutsomOperations from button CE will display in nested style CE or functions (onclick is button's CustomOperations) which is not expected right? Becuase it listed in the auto completion list but after you use it there is an error popup: This issue will cause situation: the deeper you nest your CE, the slower you get your intellisense and compilation. Because it will spend more time to lookup other CE's CustomOperations. |
What's the status on this, has this been identified yet? |
I started looking at it but got sidetracked. Going to continue once finish my nullables work |
This is becoming a show stopper for us, we are using Fun.Blazor for our UI work. And I'm seeing 50% CPU utilization on a iProcessor 13th Gen Intel(R) Core(TM) i9-13900K, 3000 Mhz, 24 Core(s), 32 Logical Processor(s) I just started to build the tooling from source for other reasons. |
Yeah, it's pretty much we do tc/resolutions for custom operations all the time from scratch. I know @T-Gro was looking into some ce-heavy code too. If you have example project, or can synthesize it, I can show how it can be profiled with ease. |
It would be really helpful to get some improvements here. CE's are really "used|abused" in F# and the compilation goes really slow at some points . |
Was there an update to this issue that would resolve this? I hadn't seen anything in the Release notes that would indicate this? Thanks, |
Not to my knowledge, no changes to CEs checking. |
@vzarytovskii @T-Gro any progress on this, it's been a while since last update. We have multiple projects are impacted by this issue. Please please improve this!!! Many many thanks!!! |
Nested CE + large DU pattern matching is getting really slow. |
No progress really, I suspect it will require substantial changes and investigation. It is committed for F#9, but I don't have a specific timeline. |
I had multiple attempts to rewrite how caching is done for the CEs, but with no luck. |
Were you able to record any of your findings somewhere? |
No writings per se, but I would be happy to meet and explain the problem. Or rather one of the problems. |
@vzarytovskii can we introduce some attributes or something else which the library author can use it to annotate the CE based DSL so the compiler can use it to compile code faster without the library consumer to do anything? If this can help, I think it is also acceptable and maybe a direction to give a try, especially if there is no way out for solving this performance issue because of how the CE currently works. |
Unlikely, CE typechecking needs a significant rewrite for it to improve |
In a big Fable project, after a big refactoring to introduce a convenience computation expression, the project started to take much longer to compile. The overhead came from the type checking phase of FSharp.Compiler.Service (it also takes a long time when running
dotnet build
). The computation expression is a convenience to generate React fragments out of React elements. The CE accepts single React Elements as well as sequences and optional elements. The code is like this:There's a similar CE
ElementsBuilder
that works the same but returnsReactElement list
instead of the fragment.Users tried changing the CE in different ways, but the only thing that worked was to remove the CE in most of the files. It is still used in some of them but compilation times are mostly back to normal.
The most interesting part is I tried profiling this, and the result is most of the time is spent in the function
FSharp.Compiler.NameResolution.ResolveLongIdentAsModuleOrNamespaceThen
. This makes me wonder if the CE is not responsible for the slow compilation but instead it causes a problematic name resolution directly. BothElementBuilder
andelement
are in the same module decorated withAutoOpen
.Any hints to improve the performance of the compilation?
The text was updated successfully, but these errors were encountered: