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

Reference equality optimisation commented out in implementation of (=) #15486

Closed
Happypig375 opened this issue Jun 25, 2023 · 4 comments
Closed
Labels
Milestone

Comments

@Happypig375
Copy link
Member

(*if objEq xobj yobj then true else *)

Why is this the case? It seems to be a low hanging optimisation that went unused especially since this optimisation is used even inside the BCL implementation of object.Equals.

https://github.com/dotnet/runtime/blob/0633ecfb79a3b2f1e4c098d1dd0166bc1ae41739/src/libraries/System.Private.CoreLib/src/System/Object.cs#L55

@Happypig375 Happypig375 added Area-Library Issues for FSharp.Core not covered elsewhere Feature Improvement Theme-Performance labels Jun 25, 2023
@github-actions github-actions bot added this to the Backlog milestone Jun 25, 2023
@vzarytovskii
Copy link
Member

  • Adding a reference equality check means the semantics of code can become really sensitive to optimizations - including Debug/Release changes. Code that works in Release can raise exceptions in Debug. Code that runs efficiently in Release can run arbitrarily slower in Debug. Infinite loops can be suppressed "by luck". 

  • There's a similar argument about "what happens when you change your code, e.g. make a copy of a list". F# programmers are just much less aware of object identity than other programmers and expect that making a copy of a list doesn't tend to much with the semantics of their code.  (They may be aware there is a potential allocation difference, but won't typically expect the complexity of their code to be so sensitive to object identity)

  • That pointer equality is a hugely important optimization for experienced F# programmers, including in rewriting - we use it extensively in the code rewrite routines of the compiler, for example.

That said in practice there would be a host of types where performing pointer equality checks would be 100% safe, e.g. int list or string list or (int * string) list.  These would loosely speaking be types with known equality semantics on the elements (no exceptions, termination, respects (X = X) == true etc.)  The problem is that the more of these special cases you bake in, the more the programmer needs to know.

To give one other example: what about let x = [NaN] in (x = x) - this should return false. 

@Happypig375
Copy link
Member Author

The NaN thing wouldn't apply to when the ER flag is true in this function. Also about optimisation sensitivity - does Debug/Release config change object identity? How is that relevant here?

@voronoipotato
Copy link
Contributor

voronoipotato commented Jun 26, 2023

The only one of these I'm really, really, really afraid of is "Infinite loops can be suppressed "by luck"." It's hard enough to explain let rec tail recursion, but if it doesn't even happen that would make my life much harder. Something that works when it shouldn't is far more harmful than something that doesn't work when it should, because it's "fail safe". Let rec was already a bit "fail dangerous" as it is. It would mean a lot to me if we can properly rule this out or prevent it before making this kind of optimization.

@0101
Copy link
Contributor

0101 commented Jul 17, 2023

This optimization is unsafe and won't be implemented in the foreseeable future.

@0101 0101 closed this as not planned Won't fix, can't repro, duplicate, stale Jul 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Archived in project
Development

No branches or pull requests

4 participants