-
Notifications
You must be signed in to change notification settings - Fork 833
WIP: Remove (non-tail) recursion and StackGuard from FindUnsolved.fs, use explicit mutable stack
#18951
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
WIP: Remove (non-tail) recursion and StackGuard from FindUnsolved.fs, use explicit mutable stack
#18951
Conversation
|
StackGuard from FindUnsolved.fs, use explicit mutable stack
|
@majocha not entirely sure what would good test be, or how to repeat tests you were performing in the |
|
It was building and editing some repos, including fantomas, IcedTasks and this one here. I'll try to find out which one was especially heavy with Yeah, it was IcedTasks all the Expecto tests, with lots of CEs. Very slow to edit in VS. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.
Bruh. Do better. |
| type env = | NoEnv | ||
|
|
||
| let FindUnsolvedStackGuardDepth = StackGuard.GetDepthOption "FindUnsolved" | ||
| type [<NoEquality; NoComparison>] WorkItem = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we use just Expr as the work item, without the wrapper type?
Loop in accExpr and pass a push to other functions. Instead of calling back to accExpr they cut short the recursion by pushing exprs?
let rec accExpr (cenv: cenv) (env: env) expr =
let stack = Stack<Expr>()
let push (e: Expr) = stack.Push e
push expr
while stack.Count > 0 do
let expr = stack.Pop() |> stripExpr
match expr with
| Expr.Sequential (e1, e2, _, _) ->
push e1
push e2
| Expr.Let (bind, body, _, _) ->
accBind cenv env bind push
push body
// ....etc.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose. I wanted to be more explicit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using Expr directly feels more direct to me as well - firstly we avoid the need to maintain a parallel hierarchy of types, second it also avoids another allocation per iteration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or even simpler, take a look please #18966
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That'll probably work, though subjectively a bit harder to understand than explicit one (everything is hidden behind special stackguard, but same goes for normal stackguard).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it's a drop-in replacement, but only for unit returning functions, so basically only here.
I tried to apply this or come up with something similar for the biggest offender, ExprFolders but the code around exprF is so general and indirect already, it fries my brain.
|
I'm afraid, I don't have free time to tinker with it anymore (this month), feel free to pick it up (should be an easy change to address the comment), or use the specialized stack guard. |


Experiment of using explicit heap-located stack instead of (non-tail) recursion for
FindUnsolvedto get rid of quite expensiveStackGuard.This is a WIP, please note that code is imperative (not piping into Option.iter or List.iter) on purpose so it is easier for me to debug and step through. If this works out I can convert to whatever style is preferred