-
Notifications
You must be signed in to change notification settings - Fork 17.3k
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: map access quite slow with interface key compared to integer key (over 10X slower) #6106
Labels
Milestone
Comments
Don't use 'interface{}' typed map keys if you're after performance. In the case of 'interface{}' typed keys, there are probably three things that must be checked _at runtime_: - If both "sides" of the cmp are of same types. - If that type has '==' defined. ([]slices do not, for example) - If the values are equal or not, but only using a dynamically dispatched "comparator" (a function call, I guess). If you compare this to the single instruction that the compiler can emit for comparing two integers, the 10 times slowdown seems to me not surprising at all. |
Issue #6105 has been merged into this issue. |
This issue was filed as a result of discussion in https://groups.google.com/d/msg/golang-dev/Oik3353DJ2w/aNxNhwC9J_kJ The genesis of the thread was to find a fast way to do comparison checks for reflect.Type or do fast map access with reflect.Type keys. I needed this because I was building an encoder where users could map reflect.Type to custom encode/decode functions. Doing a map access every time the recursive function was called caused a performance hit. This is fleshed out in that same thread above, or linked directly at https://groups.google.com/d/msg/golang-dev/Oik3353DJ2w/gPPLMfONvIAJ In that thread, Russ mentioned that interface comparison should be equivalent to 2 integer comparisons, and we can look to make operations on interfaces faster (instead of working around them). Direct link: https://groups.google.com/d/msg/golang-dev/Oik3353DJ2w/d6ei8LbyehEJ I filed the issues separately because, even though they look like the same issue to me, they might not be. Keith may look into maps with interface keys, while someone else looks into interface comparison. Can Russ weigh in on this before we finalize this as WNF, and merge both of them?. He has more context per the discussion. |
Thanks. I tried the Pointer trick 2 days ago and it worked well, giving roughly the same performance benefits as the ID() hack I tried previously (from 4-20% perf improvement). This took care of my immediate need. Having said that, I think we should keep the previous issue (6105) open at least. There may be some things we can do to improve interface comparisons in some specific scenarios: - for pointer types when the types are equal. For example, comparing reflect.Type falls into this category, and the comparison is that both are *rtype and both pointers are equal. - base types which are numbers or booleans. We could do a fast path for these common and seemingly trivial interface comparisons, to improve their performance to something less than the 20X. Currently, the 20X for equality check vs non-interface equality of same underlying value seems excessive. Disclaimer: I looked through the runtime.ifaceeq and runtime.efaceeq but couldn't figure it out. |
This issue was closed.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
The text was updated successfully, but these errors were encountered: