-
Notifications
You must be signed in to change notification settings - Fork 790
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
Use a MaxBuffer for Suggestions #7060
Conversation
3b42f78
to
c5cc18e
Compare
lol, fair play @forki , got tired waiting so integrated it all yourself! A few minor things for discussion:
Happy to discuss further but if you are happy with these modifications, I can tweak my original MaxBuffer design to include:
Thanks again for getting this worked in! |
that sounds good. Let's wait for 1h and see if we broke something so far |
Yeah, makes sense to see if your on the right track. Looking through code, |
A gift ... this makes Maxbuffer distinct and enumerable for value (seq value) open System.Collections
open System.Collections.Generic
type internal MaxBufferValueEnumerator<'k,'V>(data: KeyValuePair<'k,'V> []) =
let mutable current = data.Length
interface IEnumerator<'V> with
member x.Current with get () =
let kvpr = & data.[current]
kvpr.Value
interface System.Collections.IEnumerator with
member x.Current with get () = box data.[current].Value
member x.MoveNext() =
current <- current - 1
current >= 0
member x.Reset () = current <- data.Length
interface System.IDisposable with
member x.Dispose () = ()
type MaxBuffer<'K,'V when 'K : comparison and 'V : equality>(max:int) =
let data = Array.zeroCreate<KeyValuePair<'K,'V>>(max)
let rec backup i j =
if i < j then
data.[i] <- data.[i + 1]
backup (i + 1) j
let rec find i k v =
let kvpr : byref<_> = &data.[i] //only want key (not KVP)
let kr = kvpr.Key
if k < kr then
if i = 0 then false
else
backup 0 (i-1)
data.[i-1] <- System.Collections.Generic.KeyValuePair<_,_>(k,v)
true
else
if k = kr then // add distinct
if kvpr.Value = v then false // exact match so no insertion needed
else
backup 0 i
data.[i] <- System.Collections.Generic.KeyValuePair<_,_>(k,v)
true
elif i = max - 1 then // end of the line, replace at head
backup 0 i
data.[i] <- System.Collections.Generic.KeyValuePair<_,_>(k,v)
true
else find (i + 1) k v
member x.Insert (k,v) = find 0 k v
//member x.Result () = data
interface IEnumerable<'V> with
member x.GetEnumerator () = new MaxBufferValueEnumerator<'k,'V>(data) :> IEnumerator<'V>
interface System.Collections.IEnumerable with
member x.GetEnumerator () = new MaxBufferValueEnumerator<'k,'V>(data) :> IEnumerator |
@gerardtoconnor I had to change the buffer, since PBTs said it did not work |
98401f2
to
03a2e44
Compare
sorry, what are PBTs again? No issue with it being moved anyway. I notice on the latest commit you have changed/simplified the algo a bit, although I agree it is better to have largest value first in the data array, I think with your implementation it is checking from the head (largest) down each time... as we expect most entries to not make it into the max data array, we check at the end of the queue as its a quick short-circuit most of the time when we expect max < (suggestions / 2). Curious also, your new |
PBTs = Property based tests |
Yeah that makes sense, by not using |
@gerardtoconnor let me finish with the current version, get it green and then we improve the buffer from there. Ok? |
cb7375c
to
76dd871
Compare
b37636e
to
534d44a
Compare
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.
Overall, this is fantastic. Thank you both for doing the work and spending time analyzing the performance. It seems to be a very significant improvement and am very much in favor.
Just a few things before we merge:
- A few minor format nits.
- Duplicate code bit.
applied all feedback. thx |
Very nice work. |
@forki I'll try to get this integrated and released in a new FCS version this weekend so the change can be integrated into FSAC/ionide. |
@baronfel awesome. That would be great |
* Use MaxBuffer for Suggestions * Extract SuggestNames function * Rename Parameter * Apply feedback for formatting
This is using a constant lengeth array for Spelling Suggestions as suggested by @gerardtoconnor in #6049 (comment)
related: ionide/FsAutoComplete#427