-
Notifications
You must be signed in to change notification settings - Fork 640
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
Introduce generic linked list #2904
Conversation
|
||
// PushFront inserts e at the front of l. | ||
// If e is already in a list, l is not modified. | ||
func (l *List[T]) PushFront(e *ListElement[T]) { |
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 understand this is supposed to be a drop in replacement of containers/list, still let me ask a question.
- Wouldn't it be more natural to have methods to add a value (
PushFront/Back
InsertBefore/After
) accepting a value T instead of a ListElement[T]? - Wouldn't it be more idiomatic to signal "no next/prev element" via an error rather than a nil pointer? I guess here performance considerations may have prevailed
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.
All of the methods take in ListElement
rather than T
to allow the caller to manage all memory allocations. I'll add some helpers to expose the API with allocations.
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.
Aside from the ListElement
vs T
change, I kept the signature the same as the stdlib to allow ease of switching. (Which is why we use nil
to signal no element rather than a bool
.
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.
just nits and questions, but LGTM
Why this should be merged
Improves the performance of
linked.Hashmap#Put
by ~50%.Before:
After:
How this works
Previously, the
linked.Hashmap
depended on the "container/list" library. This resulted in 2 memory allocations.keyValue
struct that was wrapped into anany
interface.list.Element
struct enforced by thelist
functions.By implementing our own version of the linked list, we are able to use generics to avoid the memory allocation for the interface conversion.
Additionally, our version of the linked list allows allocating the
Element
externally to the list. This allows theHashmap
to maintain a free list (which isn't an increase in memory pressure, because the map never frees allocated space either).How this was tested
Hashmap
benchmark