-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
runtime: clear() is slow for maps with big capacity and small number of items #70617
Comments
Related Issues
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.) |
This is another case where I think map shrinking (#20135) is probably the right solution. |
Wouldn't shrinking the map partially defeat the original optimization though? Not saying we shouldn't shrink maps, it's just the particular example OP gave seems like a trade-off between |
As an additional note, I wonder if this is any better or worse with the Swiss map implementation in Go 1.24. |
FWIW, Keith commented on a related issue regarding clear performance for large maps for the new Swiss map implementation in #52157 (comment). |
One approach could be that the backing storage would not shrink immediately. For example, there is this comment from Keith in #54454 (comment), including:
(That is an older comment that predates the clear builtin I think, but presumably something similar could apply). |
In https://go.dev/cl/627156, I made swissmap iteration make use of the map metadata to skip runs of empty slots, which significantly speeds up iteration over large but sparse maps (-38% vs old maps). The same idea could be applied to clear to address this issue. clear will still take longer on large maps, but the increase should be less extreme. |
The issue
The following pattern is frequently used in order to avoid excess memory allocations by re-using the map:
It has been appeared that
clear(m)
performance is proportional to the number of buckets inm
. The number of buckets can grow significantly ataddSomeItemsToMap()
. After that the performance ofclear(m)
can slow down significantly (and forever), even if only a few items are added into the map on subsequent iterations.See https://philpearl.github.io/post/map_clearing_and_size/ for more details.
The solution
Go runtime must be able to switch between the algorithm, which unconditionally clears all the buckets in
m
, and the algorithm, which clears only the buckets, which contain at least a single item, depending on the ratio between the number of items in the map and the number of buckets in it. This should improve performance ofclear(m)
in the pattern above when every iteration can store widely different number of items in m.The text was updated successfully, but these errors were encountered: