-
Notifications
You must be signed in to change notification settings - Fork 18k
proposal: runtime: add way to clear and reuse a map's working storage #45328
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
Comments
What's wrong with
? |
Actually I bench this scenario too, and it loss %2~%8 cpu performance since runtime.memclr() is more effecient than foreach iteration... |
there is no iteration in the generated code. Newer go compilers optimise the above to a single call to runtime.mapclear which uses memclr. Note that this doesnt work for key types that are not reflexive for ==. A simple memclear allone doesnt suffice and other data in the map needs to be reset too to make it reusable. Line 978 in db8142f
|
I got it. As you mentioned, if the key type is complex like interface{}, this compiling-time optimization doesn't work. So my way still gets advantage? |
Sure. So the question is, is it worth complicating the API? And what would that API look like? How easy is it to use and/or how easy is it to avoid misusing it? We tend to come down on the side of a cleaner API. |
Since we have |
Having I'm not sure I understand the distinction between |
I agree with your proposal . |
We already recognize and optimize
as memset. Whatever fast implementation of map clearing we might come up with could be triggered just as easily by
right? The question is really whether the optimization of that is "zero all the storage" or "shrink". |
We already do exactly that, at least for reflexive keys (it's trickier for things like
We currently don't shrink, just zero. I think shrink should be implemented in general (#20135) before we do anything like that for this optimization in particular. The tricky part here is that I don't see an easy way to tell the runtime "Keep the storage, I'm going to reuse it ~immediately", and "Release the storage, this map is going to be much smaller from here on out". Hopefully the automatic shrink mechanism, once we have it, will be good enough. |
This proposal has been added to the active column of the proposals project |
For my personal use case (where I do the |
If I want to empty+shrink we can simply create a new map, so maybe we don't need to focus on that possibility? |
Maybe the signal is to not shrink below the initial capacity. In any event, it sounds like we don't need "a way to clear and reuse a map's working storage" because the straightforward delete loop does exactly that and does it efficiently. |
Based on the discussion above, this proposal seems like a likely decline. |
No change in consensus, so declined. |
This has been reopened in #56351, based on further thought about NaNs. |
go/src/runtime/map.go
Line 303 in db8142f
runtime.makemap()
gives a way to reuse old hmap's buckets, but it is only used when mallocating small maps on stack at present. Why not open this shortcut to users for memory reusing? Actually I only need exportingruntime.makemap()
andruntime.clearmap()
to achieve this goal:It works fine and benefits much on big maps. This is the benchmark results I got on operating a 1000-keys map (one op includes make(map[int]interface{}), set 1000 keys and get 1000 keys):
The text was updated successfully, but these errors were encountered: